Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a macro inside another macro in Twig

Tags:

twig

How button_primary macro can call button macro in Twig engine? I've tried this solution, but it doesn't work, it says that the function "button" does not exist:

{% macro button(label, type, size) %}
    {% set type = type|default('default') %}
    {% set size = size|default('large') %}
    {% set cls = ['btn'] %}

    <a href="#" class="{{ cls|join(' ') }}">{{ label }}</a>
{% endmacro %}

{% macro button_primary(label, size) %}
    {{ button(label, 'primary', size) }}
{% endmacro %}
like image 463
gremo Avatar asked Mar 03 '12 18:03

gremo


3 Answers

EDIT: As per cr4zydeejay's answer Feb 7th 2021 the answer was updated to reflect the correct way in Twig 3.x

Twig 3.x

https://twig.symfony.com/doc/3.x/tags/macro.html

When macro usages and definitions are in the same template, you don't need to import the macros as they are automatically available under the special _self variable:

    <p>{{ _self.input('password', '', 'password') }}</p>

    {% macro input(name, value, type = "text", size = 20) %}
        <input type="{{ type }}" name="{{ name }}" value="{{ value|e }}" size="{{ size }}"/>
    {% endmacro %}

Twig 2.x

Unfortunatly Gremo's answer works, but is not the right way to do it.

When you define a macro in the template where you are going to use it, you might be tempted to call the macro directly via _self.input() instead of importing it; even if seems to work, this is just a side-effect of the current implementation and it won't work anymore in Twig 2.x.

http://twig.sensiolabs.org/doc/tags/macro.html

Correct way:

    {% macro input(name, value, type, size) %}
        <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
    {% endmacro %}
    
    {% macro wrapped_input(name, value, type, size) %}
        {% import _self as forms %}
    
        <div class="field">
            {{ forms.input(name, value, type, size) }}
        </div>
    {% endmacro %}
like image 90
WTPK Avatar answered Nov 07 '22 11:11

WTPK


Answer to myself: it's a quite new feature added, see this link. Anyway the solution is using _self:

{% macro button_primary(label, size) %}
    {{ _self.button(label, 'primary', size) }}
{% endmacro %}
like image 34
gremo Avatar answered Nov 07 '22 12:11

gremo


Gremo's answer is correct way to do this in Twig 3.x.

https://twig.symfony.com/doc/3.x/tags/macro.html

When macro usages and definitions are in the same template, you don’t need to import the macros as they are automatically available under the special _self variable.

like image 2
cr4zydeejay Avatar answered Nov 07 '22 12:11

cr4zydeejay