Переопределение блоков в включенных шаблонах веток


Существует ли в целом "хороший" способ достижения этой функциональности? Я читал о теге "использовать", который пока кажется лучшим вариантом, но мне все еще не нравится, что он не позволяет мне вводить какой-либо внешний html, только блоки.

Я буду использовать тег "включить" в приведенном ниже примере, чтобы продемонстрировать намерение, которое я пытаюсь описать.

#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

Я нашел решение. Используйте функцию block(), чтобы получить содержимое дочернего блока и передать его в файл header.html.twig в качестве переменной в операторе 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, 2013-08-10 10:24:20

Проверьте тег встраивания: http://twig.sensiolabs.org/doc/tags/embed.html

Работает не совсем так, как вы хотите, но я думаю, что сейчас это настолько близко, насколько вы можете.

 5
Author: Martin, 2014-11-04 16:01:29

Я нашел хорошее и реальное решение, прочитав документацию для встраивать бирка. Я использую Twig 2.0 в Symfony 4.

Моя структура

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

С кодом выше, когда я создаю свой индекс.html.ветка единственный код, необходимый для отображения вещей по умолчанию, - это

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

И переопределять определенные блоки. Но, когда мне нужно создать другую страницу, которая использует этот скелет, если я попытаюсь переопределить блок sub_app_menu_itens в другом включенном шаблоне _partial не работает. <li>Main App Menu Item</li> всегда отображается и никогда не перезаписывается (код выше)

#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> никогда не показывается. Пробовал много вещей, таких как extends и даже условные выражения, но безуспешно.

Решение

В встраивать тег решает проблему перезаписи дочерних блоков частичных шаблонов.

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

И упрощение шаблона _partial, чтобы иметь только необходимый html

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

Сейчас <li>SubApp Menu Item</li> будет отображаться в нужном месте шаблона _menu.

Мышление на уровнях, include работает как подуровень (анализируется), и все вещи переопределяются только на одном уровне, поэтому include не позволяет переопределять в другом включении. Вместо этого шаблоны embed выводятся на один и тот же уровень (не анализируются), и поэтому вы можете переопределять вещи.

 2
Author: Marcos Regis, 2018-05-08 21:48:11

Это можно сделать. Вот мое решение проблемы путем передачи переменной в представление.

#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]);

Поскольку я использую SlimPHP, я называю его так, передавая переменную sidebar в представление. Это можно расширить, используя различные переменные, переданные в представление, чтобы вы могли выбрать sidebar1, sidebar2 и т.д.

 1
Author: kacperek, 2014-01-22 23:09:49

Я заставил его работать с очень простым взломом:

В основном он ведет себя таким образом, потому что без {% extends "foo.html.twig" %} он не понимает блоки и просто отображает их на месте.

Итак, давайте расширим... ничего:

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

Это ничто на самом деле всего лишь 1 блок:

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

Единственное, что вам нужно, это завернуть все в блок, этот фальшивый "основной" блок.

 0
Author: lipsumar, 2017-05-16 15:56:13