Overriding blocks within included Twig templates

前端 未结 5 943
北荒
北荒 2020-12-12 21:19

Is there a generally \"good\" way to achieve this functionality? I have read about the \'use\' tag, which seems like the best option so far, but I still don\'t like that it

5条回答
  •  北海茫月
    2020-12-12 21:38

    I found a good and real solution reading the documentation for the embed tag. I'm using Twig 2.0 in Symfony 4.

    My structure

    #templates/base.html.twig
    {% block navbar %}
        
    {% endblock navbar %}
    {% block content %}
        {# several blocks defined #}
        {% block footer '' %}
    {% endblock content %}
    
    #templates/_menu.html.twig
    
      {% block sub_app_menu_itens %}
    • Main App Menu Item
    • {% endblock sub_app_menu_itens %}
    • Menu item
    • Another menu item
    • Yet another menu item

    With code above, when I create my index.html.twig the only code needed to show de default things is

    #templates/index.html.twig
    {% extends 'base.html.twig' %}
    

    and override blocks defined. But, when I need to create another page, that use these skeleton, if I try to override block sub_app_menu_itens in another _partial template included, doesn't work.

  • Main App Menu Item
  • is always showed and never overwritten (code above)

    #templates/subapp/index.html.twig
    {% extends 'base.html.twig' %}
    {% block title %}{{ 'agencia.homepage'|trans }}{% endblock %}
    {% block menu %}
        {% include 'subapp/_menu.html.twig' %}
    {% endblock menu %}
    {% block user_content %}Content Here{% endblock %}
    
    #templates/subapp/_menu.html.twig
    {% extends '_menu.html.twig' %}
    {% block sub_app_menu_itens %}
            
  • SubApp Menu Item
  • {% endblock sub_app_menu_itens %}

  • SubApp Menu Item
  • is never showed. Tried a lot of things like extends and even conditionals with no luck.

    THE Solution

    The embed tag solve the child partial templates blocks to be overwritten.

    #templates/subapp/index.html.twig
    {% block menu %}
        {% embed '_menu.html.twig' %}
            {% block sub_app_menu_itens %}
                {% include 'subapp/_menu.html.twig' %}
            {% endblock sub_app_menu_itens %}
        {% endembed %}
    {% endblock menu %}
    

    And simplifing _partial template to have only the html needed

    #templates/subapp/_menu.html.twig 
        
  • SubApp Menu Item
  • Now

  • SubApp Menu Item
  • will be displayed on the right place of _menu template.

    Thinking in levels, a include works like a sublevel (parsed) and all things are only override on the same level, so include doesn't allow to override in another include. Instead, embed templates are bring to the same level (not parsed) and so you can override things.

提交回复
热议问题