Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Add "title" argument to Twig svg() function #3937

benface opened this issue Mar 2, 2019 · 5 comments


Copy link

commented Mar 2, 2019

The <title> tag of an <svg> can be used to provide alternative text for accessibility reasons. It would be nice if we could add/replace the <title> tag when inlining SVGs with the svg() function in Twig. Sometimes the same icon can mean different things depending on the context, or on a multilingual site you may want to translate it.


This comment has been minimized.

Copy link

commented Mar 3, 2019

I could envision a more general tags param being useful. It could accept an array of tag names as keys, and markup as values — to allow adding/replacing title or desc.


This comment has been minimized.

Copy link

commented Jul 26, 2019

Closing this in favor of #4660

gtettelaar added a commit to gtettelaar/cms that referenced this issue Aug 15, 2019
Take craftcms#3937 into account
Turns out there was a use case for custom elements.

Also some cleanup and docs for the new $elements functionality.

This comment has been minimized.

Copy link

commented Aug 16, 2019

Sorry, just realized this is referring to a <title> HTML element, not the title attribute. Reopening.


This comment has been minimized.

Copy link

commented Aug 19, 2019

Just added new |append and |prepend Twig filters for Craft 3.3, which append/prepend HTML elements to another element, including SVGs.

{{ svg('@webroot/icons/wave.svg')
    |append('<title>Waving Hand</title>')
    |append('<desc>A waving hand icon.</desc>') }}

If you think the SVG may already contain <title> / <desc> elements, then you can pass a second argument that determines how that should be handled to avoid duplicate elements:

  • 'keep' will leave the existing element alone and not add the new one
  • 'replace' will replace the existing element with the new one
{{ svg('@webroot/icons/wave.svg')
    |append('<title>Waving Hand</title>', 'keep')
    |append('<desc>A waving hand icon.</desc>', 'replace') }}

I’ve also added a new tag() Twig function, for rendering HTML tags using a declarative syntax:

{{ svg('@webroot/icons/wave.svg')
    |append(tag('title', {text: 'Waving Hand'}), 'keep')
    |append(tag('desc', {text: 'A waving hand icon.'}), 'replace') }}

You can combine these new filters with the new |attr filter as well:

{{ svg('@webroot/icons/wave.svg')
    |attr({role: 'img', 'aria-labelledby': 'title  desc'})
    |append(tag('title', {id: 'title', text: 'Waving Hand'}), 'replace')
    |append(tag('desc', {id: 'text', text: 'A waving hand icon.'}), 'replace') }}

Or even move all this into a custom macro:

{% macro accessibleSvg(svg, title, desc) %}
    {%- set ns = 'svg' ~ random() %}
    {{- svg(svg)
        |attr({role: 'img', 'aria-labelledby': "#{ns}-title  #{ns}-desc"})
        |append(tag('title', {id: "#{ns}-title", text: title}), 'replace')
        |append(tag('desc', {id: "#{ns}-desc", text: desc}), 'replace') }}
{%- endmacro %}

{{ _self.accessibleSvg(
    'Waving Hand',
    'A waving hand icon.'
) }}

This comment has been minimized.

Copy link
Contributor Author

commented Aug 19, 2019

Very cool! 👍

@brandonkelly brandonkelly added this to the 3.3 milestone Aug 19, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
3 participants
You can’t perform that action at this time.