Spec-Zone.ru › Twig 1

extends

Тег extends может быть использован для расширения шаблона из другого шаблона.

Примечание

Как и PHP, Twig не поддерживает множественное наследование. Поэтому вы можете использовать только один тег extends за раз при рендеринге. Однако Twig поддерживает горизонтальное использование.

Давайте определим базовый шаблон, base.html, который определяет простой HTML-шаблон документа:

<!DOCTYPE html>
<html>
    <head>
        {% block head %}
            <link rel="stylesheet" href="style.css"/>
            <title>{% block title %}{% endblock %} - My Webpage</title>
        {% endblock %}
    </head>
    <body>
        <div id="content">{% block content %}{% endblock %}</div>
        <div id="footer">
            {% block footer %}
                &copy; Copyright 2011 by <a href="http://domain.invalid/">you</a>.
            {% endblock %}
        </div>
    </body>
</html>

В этом примере теги block определяют четыре блока, которые могут быть заполнены дочерними шаблонами.

Тег block просто сообщает движку шаблонов, что дочерний шаблон может переопределить эти части шаблона.

Дочерний шаблон

Дочерний шаблон может выглядеть так:

{% extends "base.html" %}

{% block title %}Index{% endblock %}
{% block head %}
    {{ parent() }}
    <style type="text/css">
        .important { color: #336699; }
    </style>
{% endblock %}
{% block content %}
    <h1>Index</h1>
    <p class="important">
        Welcome on my awesome homepage.
    </p>
{% endblock %}

Тег extends является ключевым. Он сообщает движку шаблонов, что этот шаблон «расширяет» другой шаблон. Когда система шаблонов оценивает этот шаблон, сначала она находит родительский шаблон. Тег extends должен быть первым тегом в шаблоне.

Обратите внимание, что поскольку дочерний шаблон не определяет блок footer, вместо этого используется значение из родительского шаблона.

Вы не можете определить несколько тегов block с одинаковым именем в одном шаблоне. Это ограничение существует, потому что тег block работает «в обоих» направлениях. То есть, тег block не только предоставляет пустое место для заполнения, но также определяет содержимое, которое заполняет это место в родительском шаблоне. Если в шаблоне были бы два тега с одинаковыми именами block, родительский шаблон не знал бы, какой из блоков использовать.

Если вы хотите отобразить блок несколько раз, вы можете использовать функцию block:

<title>{% block title %}{% endblock %}</title>
<h1>{{ block('title') }}</h1>
{% block body %}{% endblock %}

Родительские блоки

Возможна отрисовка содержимого родительского блока с помощью функции parent. Это возвращает результат родительского блока:

{% block sidebar %}
    <h3>Table Of Contents</h3>
    ...
    {{ parent() }}
{% endblock %}

Именованные теги закрытия блоков

Twig позволяет указать имя блока после тега закрытия для лучшей читабельности (имя после слова endblock должно совпадать с именем блока):

{% block sidebar %}
{% block inner_sidebar %}
        ...
{% endblock inner_sidebar %}
{% endblock sidebar %}

Вложенность и область видимости блоков

Блоки могут быть вложены для более сложных макетов. По умолчанию блоки имеют доступ к переменным из внешних областей видимости:

{% for item in seq %}
    <li>{% block loop_item %}{{ item }}{% endblock %}</li>
{% endfor %}

Сокращения блоков

Для блоков с небольшим содержимым возможна сокращенная запись. Следующие конструкции делают одно и то же:

{% block title %}
{{ page_title|title }}
{% endblock %}
{% block title page_title|title %}

Динамическое наследование

Twig поддерживает динамическое наследование, используя переменную в качестве базового шаблона:

{% extends some_var %}

Если переменная принимает значение экземпляра \Twig\Template или \Twig\TemplateWrapper, Twig будет использовать его в качестве родительского шаблона:

// {% extends layout %}

// deprecated as of Twig 1.28
$layout = $twig->loadTemplate('some_layout_template.twig');

// as of Twig 1.28
$layout = $twig->load('some_layout_template.twig');

$twig->display('template.twig', ['layout' => $layout]);

Новое в версии 1.2: Возможность передачи массива шаблонов добавлена в Twig 1.2.

Вы также можете предоставить список шаблонов, проверяемых на существование. Первый существующий шаблон будет использован как родительский:

{% extends ['layout.html', 'base_layout.html'] %}

Условное наследование

Поскольку имя шаблона родителя может быть любым допустимым выражением Twig, возможно сделать механизм наследования условным:

{% extends standalone ? "minimum.html" : "base.html" %}

В этом примере шаблон будет расширять шаблон макета «minimum.html», если переменная standalone имеет значение true, и «base.html» в противном случае.

Как работают блоки?

Блок предоставляет способ изменить рендеринг определенной части шаблона, но никак не влияет на логику вокруг него.

Давайте рассмотрим следующий пример, чтобы проиллюстрировать, как работает блок, и, что более важно, как он не работает:

{# base.twig #}
{% for post in posts %}
    {% block post %}
        <h1>{{ post.title }}</h1>
        <p>{{ post.body }}</p>
    {% endblock %}
{% endfor %}

Если вы отобразите этот шаблон, результат будет точно таким же с тегом block или без него. Тег block внутри цикла for просто делает его переопределяемым дочерним шаблоном:

{# child.twig #}
{% extends "base.twig" %}

{% block post %}
    <article>
        <header>{{ post.title }}</header>
        <section>{{ post.text }}</section>
    </article>
{% endblock %}

Теперь, при отображении дочернего шаблона, цикл будет использовать блок, определенный в дочернем шаблоне, а не в базовом. Выполняемый шаблон тогда эквивалентен следующему:

{% for post in posts %}
    <article>
        <header>{{ post.title }}</header>
        <section>{{ post.text }}</section>
    </article>
{% endfor %}

Давайте рассмотрим другой пример: блок, включенный в оператор if:

{% if posts is empty %}
    {% block head %}
        {{ parent() }}

        <meta name="robots" content="noindex, follow">
    {% endblock head %}
{% endif %}

Вопреки тому, что вы могли бы подумать, этот шаблон не определяет блок условно; он просто делает переопределяемым дочерним шаблоном вывод того, что будет отображено, когда условие равно true.

Если вы хотите, чтобы вывод отображался условно, используйте следующее вместо этого:

{% block head %}
    {{ parent() }}

    {% if posts is empty %}
        <meta name="robots" content="noindex, follow">
    {% endif %}
{% endblock head %}

См. также

block, block, parent, use

« embed | filter »

© 2009–2018 by the Twig Team
Licensed under the three clause BSD license.
The Twig logo is © 2010–2020 Symfony
https://twig.symfony.com/doc/1.x/tags/extends.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API