embed
Тэг embed объединяет поведение тегов include и extends. Он позволяет включать содержимое другого шаблона, точно так же, как это делает include. Но также он позволяет переопределять любые блоки, определённые внутри включённого шаблона, как при расширении шаблона.
Представьте вложенный шаблон как «микро-скелет макета».
{% embed "teasers_skeleton.twig" %}
{# These blocks are defined in "teasers_skeleton.twig" #}
{# and we override them right here: #}
{% block left_teaser %}
Some content for the left teaser box
{% endblock %}
{% block right_teaser %}
Some content for the right teaser box
{% endblock %}
{% endembed %}
Тэг embed поднимает идею наследования шаблонов на уровень фрагментов содержимого. В то время как наследование шаблонов позволяет создавать «скелеты документов», которые наполняются жизнью дочерними шаблонами, тэг embed позволяет создавать «скелеты» для более мелких единиц содержимого и повторно использовать и заполнять их где угодно.
Поскольку целевое применение может быть не очевидным, давайте рассмотрим упрощённый пример. Представьте базовый шаблон, общий для нескольких HTML-страниц, определяющий один блок под названием «содержимое»:
┌─── page layout ─────────────────────┐
│ │
│ ┌── block "content" ──┐ │
│ │ │ │
│ │ │ │
│ │ (child template to │ │
│ │ put content here) │ │
│ │ │ │
│ │ │ │
│ └─────────────────────┘ │
│ │
└─────────────────────────────────────┘
Некоторые страницы («foo» и «bar») используют ту же структуру содержимого — два вертикально расположенных блока:
┌─── page layout ─────────────────────┐
│ │
│ ┌── block "content" ──┐ │
│ │ ┌─ block "top" ───┐ │ │
│ │ │ │ │ │
│ │ └─────────────────┘ │ │
│ │ ┌─ block "bottom" ┐ │ │
│ │ │ │ │ │
│ │ └─────────────────┘ │ │
│ └─────────────────────┘ │
│ │
└─────────────────────────────────────┘
В то время как другие страницы («boom» и «baz») используют другую структуру содержимого — два блока, расположенных рядом:
┌─── page layout ─────────────────────┐
│ │
│ ┌── block "content" ──┐ │
│ │ │ │
│ │ ┌ block ┐ ┌ block ┐ │ │
│ │ │"left" │ │"right"│ │ │
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
│ │ └───────┘ └───────┘ │ │
│ └─────────────────────┘ │
│ │
└─────────────────────────────────────┘
Без тега embed, у вас есть два способа разработки шаблонов:
- Создать два «промежуточных» базовых шаблона, расширяющих основной макет: один с вертикально расположенными блоками для использования на страницах «foo» и «bar», и другой с блоками, расположенными рядом, для страниц «boom» и «baz».
- Встроить разметку для верхних/нижних и левых/правых блоков непосредственно в каждый шаблон страницы.
Эти два решения не масштабируются, потому что у каждого есть существенный недостаток:
- Первое решение может сработать для этого упрощенного примера. Но представьте, что мы добавим сайдбар, который может содержать разные повторяющиеся структуры содержимого. Теперь нам нужно будет создавать промежуточные базовые шаблоны для всех возможных комбинаций структуры содержимого и структуры сайдбара… и так далее.
- Второе решение подразумевает дублирование общего кода со всеми его негативными последствиями: любое изменение требует поиска и редактирования всех соответствующих копий структуры, правильность каждой копии должна проверяться, копии могут стать несинхронизированными из-за неосторожных изменений и т. д.
В такой ситуации тег embed становится полезным. Общий код макета может храниться в одном базовом шаблоне, а две различные структуры содержимого, назовём их «микро-макеты», хранятся в отдельных шаблонах, которые подключаются по необходимости:
Шаблон страницы foo.twig:
{% extends "layout_skeleton.twig" %}
{% block content %}
{% embed "vertical_boxes_skeleton.twig" %}
{% block top %}
Some content for the top box
{% endblock %}
{% block bottom %}
Some content for the bottom box
{% endblock %}
{% endembed %}
{% endblock %}
И вот код для vertical_boxes_skeleton.twig:
<div class="top_box">
{% block top %}
Top box default content
{% endblock %}
</div>
<div class="bottom_box">
{% block bottom %}
Bottom box default content
{% endblock %}
</div>
Цель шаблона vertical_boxes_skeleton.twig — вынести разметку HTML для блоков.
Тэг embed принимает те же самые аргументы, что и тэг include:
{% embed "base" with {'foo': 'bar'} %}
...
{% endembed %}
{% embed "base" with {'foo': 'bar'} only %}
...
{% endembed %}
{% embed "base" ignore missing %}
...
{% endembed %}
Предупреждение
Поскольку у вложенных шаблонов нет «имен», стратегии автоматического экранирования, основанные на имени шаблона, не будут работать как ожидается, если вы измените контекст (например, если вы вложите шаблон CSS/JavaScript в HTML-шаблон). В этом случае явным образом установите стратегию автоматического экранирования по умолчанию с помощью тега autoescape.
См. также
© 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/2.x/tags/embed.html