Skip to content

Instantly share code, notes, and snippets.

@shgysk8zer0
Last active August 29, 2015 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shgysk8zer0/36f5edbefba6b6806677 to your computer and use it in GitHub Desktop.
Save shgysk8zer0/36f5edbefba6b6806677 to your computer and use it in GitHub Desktop.
SVG <symbol> concatontation
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
{
"icons": [
"red.svg",
"green.svg"
],
"output": "combined.svg"
}
<?php
require __DIR__ . DIRECTORY_SEPARATOR . 'main.php';
$icons = json_decode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'icons.json'));
SVG_symbols($icons->icons, $icons->output);
?>
<!doctype html>
<html>
<head>
<title>SVG &lt;use&gt; Demo</title>
<meta charset="UTF-8"/>
<meta name="description" content="SVG &lt;use&gt; is like an SVG sprite"/>
<meta name="keywords" content="SVG, use, sprite"/>
</head>
<body>
<!--Use SVG icons from external source-->
<?=SVG_use('red');?>
<?=SVG_use('green');?>
<!--Use SVG icons from Document-->
<?=SVG_use('red', null, null);?>
<?=SVG_use('green', null, null);?>
<!--Load the SVG Symbols to Document (need to hide them)-->
<span hidden><?=SVG_symbols($icons->icons);?></span>
</body>
</html>
<?php
/**
* Concatonate an array of SVG files into a single SVG as <symbol>s
*
* If $output is given, the results will be saved to that file.
* Otherwise, the results will be returned as a string.
*
* @param array $svgs [Array of SVG files]
* @param string $output [Optional name of output file]
* @link http://css-tricks.com/svg-symbol-good-choice-icons/
*/
function SVG_symbols(array $svgs, $output = null) {
$dom = new \DOMDocument('1.0');
$svg = $dom->appendChild(new \DOMElement('svg', null, 'http://www.w3.org/2000/svg'));
array_map(function($file) use (&$dom){
$tmp = new \DOMDocument('1.0');
$svg = file_get_contents($file);
if(is_string($svg) and @file_exists($file)) {
$svg = str_replace(["\r", "\n", "\t"], [], $svg);
$svg = preg_replace('/<!--(?!\s*(?:\[if [^\]]+]|<!|>))(?:(?!-->).)*-->/', null, $svg);
$svg = preg_replace(['/^\<svg/', '/\<\/svg\>/'], ['<symbol', '</symbol>'], $svg);
$tmp->loadXML($svg);
$tmp->getElementsByTagName('symbol')->item(0)->setAttribute('id', pathinfo($file, PATHINFO_FILENAME));
$symbol = $dom->importNode($tmp->getElementsByTagName('symbol')->item(0), true);
$dom->documentElement->appendChild($symbol);
}
}, $svgs);
$results = $dom->saveXML($dom->getElementsByTagName('svg')->item(0));
if(is_string($output)) {
file_put_contents($output, $results);
}
else {
return $results;
}
}
/**
* Quick way to use an SVG <symbol>
*
* @param string $icon [ID from the SVG source's symbols]
* @param array $attributes [key => value set of attributes to set on SVG]
* @param string $src [The link to the SVG file to use]
* @return string [HTML/SVG element containing a <use>]
*
* @uses DOMDocument, DOMElement
*/
function SVG_use($icon, array $attributes = null, $src = 'combined.svg') {
$dom = new \DOMDocument('1.0');
$svg = $dom->appendChild(new \DOMElement('svg', null, 'http://www.w3.org/2000/svg'));
$svg->setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
$svg->setAttribute('version', '1.1');
$use = $svg->appendChild(new \DOMElement('use'));
$use->setAttribute('xlink:href', "{$src}#{$icon}");
if(is_array($attributes)) {
foreach($attributes as $attr => $val) {
$svg->setAttribute($attr, $val);
}
}
return $dom->saveXML($dom->getElementsByTagName('svg')->item(0));
}
?>
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment