Spec-Zone.ru › Twig 3

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:

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

$layout = $twig->load('some_layout_template.twig');

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

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

{% 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 | flush »

© 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/3.x/tags/extends.html

Spec-Zone.ru

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