Macros are one of the most important features of the Twig template language to avoid repetitive contents. In Twig 2.11, usage of macros was simplified and other features were added to help you work with macros.
Macros are similar to PHP functions because you can pass arguments to them and the contents generated inside the macro are returned to include them in the place where the macro is called.
On symfony.com we use macros for example to display the "contributor box" in several places to highlight our amazing Symfony code and docs contributors:
1 2 3 4 5 6 | {% macro contributor_details(contributor, vertical_layout = false) %}
<div class="d-flex">
<img class="avatar {{ vertical_layout ? 'm-b-15' }}" src="...">
Thanks {{ contributor.name }} for being a Symfony contributor.
</div>
{% endmacro %}
|
Before calling to a macro in a template you must import it, even if the macro
is defined in the same template. This behavior always felt confusing to some
people and made using macros a bit annoying. Starting from Twig 2.11, we've fixed
that and macros defined in the same template are imported automatically
under the special variable _self
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | {# templates/some-template.html.twig #}
{% macro contributor_details(contributor, vertical_layout = false) %}
<div class="d-flex">
<img class="avatar {{ vertical_layout ? 'm-b-15' }}" src="...">
Thanks {{ contributor.name }} for being a Symfony contributor.
</div>
{% endmacro %}
{# ... #}
{% for contributor in contributors %}
{# you don't have to import the macro before using it #}
{{ _self.contributor_details(contributor) }}
{% endfor %}
|
This automatic import also works for macros themselves, so you can call to a macro inside another macro of the same template without importing it explicitly (this also works for any macro imported globally in the template):
1 2 3 4 5 6 7 8 9 | {% macro contributor_details(contributor, vertical_layout = false) %}
{# ... #}
{% endmacro %}
{% macro contributor_list(contributors) %}
{% for contributor in contributors %}
{{ _self.contributor_details(contributor) }}
{% endfor %}
{% endmacro %}
|
Another new feature introduced in Twig 2.11 is the support for checking the
existence of macros before calling to them thanks to the is defined
test.
It works both for macros imported explicitly and for auto-imported macros:
1 2 3 4 5 | {% import 'templates/_macros.html.twig' as macros %}
{% if macros.contributor_details is defined %}
{# ... #}
{% endif %}
|
The scoping rules that define which macros are available inside each element of each template have changed as of Twig 2.11 as follows:
{% block %}
tag are only defined inside that
block and override other macros with the same name imported in the template.
Same for macros imported explicitly inside a {% macro %}
tag.Recent Twig versions have fixed some edge-cases related to macros (e.g. calling a macro imported in a block from a nested block, etc.) and improved other error messages to make them crystal clear and help you debug issues more easily. Twig has also fixed a partial output leak that could happen when a PHP fatal error occurs.
What a Symfony developer should know about the framework: News, Jobs, Tweets, Events, Videos,...