Macros imported in a template are not accessible in embed tags of the same template.
With following templates:
foo.html.twig
{% import 'bar.html.twig' as bar_macros %}
{% embed 'baz.html.twig' %}
{% block baz %}
{{ bar_macros.bar() }}
{% endblock %}
{% endembed %}
bar.html.twig
{% macro bar() %}
BAR
{% endmacro %}
baz.html.twig
{% block baz %}{% endblock %}
trying to render foo.html.twig will throw an exception: Twig_Error_Runtime: Accessing Twig_Template attributes is forbidden.
The only workaround I found is to import the macros inside the embed tag. Explicitly passing bar_macros using with keyword does not help. I have this issue with Twig 2.3.0, is it the expected behavior?
https://twig.sensiolabs.org/doc/2.x/tags/embed.html
An embed is rendered in it's own contexts, so other then passing variables it doesn't inherit anything from it's parent.
This is not true: embed tags do have access to variables from the context they are declared in unless you use the only keyword, just like with include tags.
Anyway, passing the imported macro explicitly to the embed tag like this:
{% embed 'baz.html.twig' with {'bar_macros': bar_macros} %}
{% block baz %}
{{ bar_macros.bar() }}
{% endblock %}
{% endembed %}
does not work either.
This also fails with macros from the same template:
{% macro bar() %}
BAR
{% endmacro %}
{% embed 'baz.html.twig' %}
{% import _self as bar_macros %}
{% block baz %}
{{ bar_macros.bar() }}
{% endblock %}
{% endembed %}
but the error is different: Error: Call to undefined method __TwigTemplate_[...]::macro_bar().
Replacing _self with the name of the current template works.
@julienfalque _self refers to the anonymous template inside the {% embed %} tag, not to the main template. This is why it does not work.
Wouldn't it be more convenient that _self always refers to the actual "main" template it is used in? I suppose this would be a BC break though.
This solution seems to work
{% embed 'baz.html.twig' with {'bar': bar_macros.bar()} %}
{% block baz %}
{{ bar|raw }}
{% endblock %}
{% endembed %}
In #3012, I've fixed the error message to be more meaningful. #3012 already clarifies the rules. Here, you must import the macros in the embed tag.
Most helpful comment
This solution seems to work