Add optional parameter to prefix all IDs within SVG to avoid clashes
Purpose
Provide a way to prevent clashes between IDs used in SVGs.
The problem it solves
When an SVG is used more than once on a page, any IDs used within in the SVG will not be unique. This can cause problems when an SVG is relying on an ID (eg. for a clip-path or linear-gradient), as it can be referencing the wrong one. (Particularly a problem when you're animating SVGs!)
ID clashes often occur across multiple SVGs too, particularly when the IDs used are vague (eg. id="gradient1") or have been exported from another tool (eg. id="Layer1").
The solution
I've added another parameter to the @svg directive called $id_prefix. It allows the developer to provide a string that will be prefixed to all the IDs used within the SVG.
Usage and example
You may be using the same logo in the header and footer of the site. If the logo relies on an ID (eg. for a linear-gradient), there will be an ID clash. To get around this, you'd just pass different prefixes to the directive.
@svg('images.logo', 'w-32', ['aria-label' => 'Logo'], 'header-logo')
A detailed example
Without providing an ID prefix, my SVG markup looks like this. (This SVG was exported from Illustrator, and run manually through SVGOMG which simplified the ID to just a – optimised, but not super helpful...
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<defs>
<linearGradient id="a" x1="0" x2="100" y1="50" y2="50" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#b6ff2a" />
<stop offset=".995" stop-color="#0097ff" />
</linearGradient>
</defs>
<path fill="url(#a)"
d="M50 0C22.386 0 0 22.386 0 50s22.386 50 50 50 50-22.386 50-50S77.614 0 50 0Zm0 92.148C26.722 92.148 7.852 73.278 7.852 50S26.722 7.852 50 7.852 92.148 26.722 92.148 50 73.278 92.148 50 92.148Z"/>
</svg>
@svg('images.logo', 'w-32', ['aria-label' => 'Logo'], 'header-logo')
Passing an $id_prefix parameter to the @svg directive turns my SVG's unhelpful ID of a into the more specific header-logo-a, both where it's declared on the linearGradient in defs and where it's referenced as the fill on the path.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<defs>
<linearGradient id="header-logo-a" x1="0" x2="100" y1="50" y2="50" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#b6ff2a" />
<stop offset=".995" stop-color="#0097ff" />
</linearGradient>
</defs>
<path fill="url(#header-logo-a)"
d="M50 0C22.386 0 0 22.386 0 50s22.386 50 50 50 50-22.386 50-50S77.614 0 50 0Zm0 92.148C26.722 92.148 7.852 73.278 7.852 50S26.722 7.852 50 7.852 92.148 26.722 92.148 50 73.278 92.148 50 92.148Z"/>
</svg>
tldr;
With the addition of an $id_prefix parameter to the @svg directive, the developer is back in control of how unique an SVG's IDs are, even if that SVG is stored in the CMS.
This sounds good!
I changed your implementation slightly to instead be passed as an options array like ['idPrefix' => 'example-'] that way if there is more functionality that gets added down the road, the function doesn't start getting overloaded or introduce breaking changes.
Let me know if that's ok and that everything is still working and I can get this merged.
Thanks!
I realised I committed without the vital part of the preg_replace replacement pattern... I've added it back in! It's all working now.
The options array makes sense, thanks for changing that. This is such a helpful package for me, and it's nice to be able to contribute!