Sobreescribir bloques dentro de las plantillas de ramitas incluidas


¿ Existe una forma generalmente "buena" de lograr esta funcionalidad? He leído sobre la etiqueta' use', que parece ser la mejor opción hasta ahora, pero todavía no me gusta que no me permita traer ningún html externo, solo bloques.

Usaré la etiqueta 'include' en el ejemplo a continuación para demostrar la intención que estoy tratando de describir.

#base.html.twig
{% include 'elements/header.html.twig' %}
{% block content %}{% endblock %}
{% include 'elements/footer.html.twig' %}

#header.html.twig
<h1>This is my header</h1>
{% block page_title %} Default Page Title {% endblock %}

#index.html.twig
{% extends 'layouts/base.html.twig' %}
{# I want to be able to do this somehow #}
{% block page_title %} This is my overridden page title {% endblock %}
{% block content %} here is the index page content {% endblock %}
 42
Author: bruchowski, 2013-07-20

5 answers

Encontré una solución. Use la función block () para obtener el contenido del bloque del niño y pasarlo a header.HTML.ramita como variable en la instrucción include:

#base.html.twig
{% include 'elements/header.html.twig' with {page_title: block('page_title')} %}
{% block content %}{% endblock %}
{% include 'elements/footer.html.twig' %}

#header.html.twig
<h1>This is my header</h1>
{% if page_title is empty %}
Default Page Title
{% else %}
{{ page_title }}
{% endif %}

#index.html.twig
{% extends 'layouts/base.html.twig' %}
{% block page_title %} This is my overridden page title {% endblock %}
{% block content %} here is the index page content {% endblock %}
 51
Author: Webberig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-10 10:24:20

Echa un vistazo a la etiqueta de inserción: http://twig.sensiolabs.org/doc/tags/embed.html

No funciona exactamente como quieres pero creo que es lo más cerca que puedes estar ahora mismo.

 5
Author: Martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-04 16:01:29

Encontré una solución buena y real leyendo la documentación para el insertar tag. Estoy usando Twig 2.0 en Symfony 4.

Mi estructura

#templates/base.html.twig
{% block navbar %}
    <nav>
    {% block menu %}
        {% include '_menu' %}
    {% endblock menu %}
    </nav>
{% endblock navbar %}
{% block content %}
    {# several blocks defined #}
    {% block footer '' %}
{% endblock content %}

#templates/_menu.html.twig
<ul>
    {% block sub_app_menu_itens %}
        <li>Main App Menu Item</li>
    {% endblock sub_app_menu_itens %}
    <li>Menu item</li>
    <li>Another menu item</li>
    <li>Yet another menu item</li>
</ul>

Con el código anterior, cuando creo mi índice.HTML.ramita el único código necesario para mostrar las cosas por defecto es

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

Y sobrescribir bloques definidos. Pero, cuando necesito crear otra página, que utilizan estos esqueleto, si intento anular bloque sub_app_menu_itens en otra plantilla _partial incluida, no funciona. <li>Main App Menu Item</li> siempre se muestra y nunca se sobrescribe (código anterior)

#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 %}
        <li>SubApp Menu Item</li> 
{% endblock sub_app_menu_itens %}

<li>SubApp Menu Item</li> nunca se mostró. Probé muchas cosas como extends e incluso condicionales sin suerte.

LA Solución

El insertar etiqueta resuelve los bloques secundarios de plantillas parciales que se sobrescribirán.

#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 %}

Y simplificando la plantilla _partial para tener solo el html necesario

#templates/subapp/_menu.html.twig 
    <li>SubApp Menu Item</li> 

Ahora <li>SubApp Menu Item</li> se mostrará en el lugar correcto de la plantilla _menu.

Pensando en niveles, un include funciona como un subnivel (analizado) y todas las cosas solo son sobreescritas en el mismo nivel, por lo que include no permite sobreescribir en otro include. En su lugar, las plantillas embed se llevan al mismo nivel (no se analizan) y, por lo tanto, puede reemplazar las cosas.

 2
Author: Marcos Regis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-08 21:48:11

Se puede hacer. Aquí está mi solución al problema pasando una variable a la vista.

#layout.twig
{% if sidebar is empty %}
    This is the default sidebar text.
{% else %}
    {% block sidebar %}{% endblock %}
{% endif %}
{% block content %}{% endblock %}

#index.twig
{% extends "layout.twig" %}
{% block sidebar %}
    This is the sidebar. It will override the default text.
{% endblock %}

{% block content %}
    This is the content.
{% endblock %}

#index.php (SlimPHP)
$app->render('index.twig', ['sidebar' => true]);

Ya que estoy usando SlimPHP la forma en que lo llamo es pasando sidebar variable a la vista. Esto se puede ampliar aún más mediante el uso de diferentes variables pasadas a la vista, por lo que puede seleccionar sidebar1, sidebar2 etc.

 1
Author: kacperek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-22 23:09:49

Lo conseguí para trabajar con un truco muy simple:

Básicamente se comporta de esta manera porque sin un {% extends "foo.html.twig" %} no entiende los bloques y simplemente los renderiza en su lugar.

Así que vamos a extender... nada:

{% extends "nothing.html.twig" %}

Esto nada es realmente solo 1 bloque:

# nothing.html.twig
{% block main %}
{% endblock %}

Lo único es que necesitas envolver todo en un bloque, este bloque "principal" falso.

 0
Author: lipsumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-16 15:56:13