embed
embed
标签结合了 include 和 extends 的行为。它允许您包含另一个模板的内容,就像 include
所做的那样。但它也允许您覆盖包含的模板中定义的任何块,就像扩展模板时一样。
将嵌入式模板视为“微型布局框架”。
1 2 3 4 5 6 7 8 9 10
{% embed "teasers_skeleton.html.twig" %}
{# These blocks are defined in "teasers_skeleton.html.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 页面共享的基础模板,定义了一个名为“content”的块
1 2 3 4 5 6 7 8 9 10 11 12
┌─── page layout ─────────────────────┐
│ │
│ ┌── block "content" ──┐ │
│ │ │ │
│ │ │ │
│ │ (child template to │ │
│ │ put content here) │ │
│ │ │ │
│ │ │ │
│ └─────────────────────┘ │
│ │
└─────────────────────────────────────┘
一些页面(“page_1”和“page_2”)共享相同的内容结构 - 两个垂直堆叠的框
1 2 3 4 5 6 7 8 9 10 11 12
┌─── page layout ─────────────────────┐
│ │
│ ┌── block "content" ──┐ │
│ │ ┌─ block "top" ───┐ │ │
│ │ │ │ │ │
│ │ └─────────────────┘ │ │
│ │ ┌─ block "bottom" ┐ │ │
│ │ │ │ │ │
│ │ └─────────────────┘ │ │
│ └─────────────────────┘ │
│ │
└─────────────────────────────────────┘
而其他页面(“page_3”和“page_4”)共享不同的内容结构 - 两个并排的框
1 2 3 4 5 6 7 8 9 10 11 12
┌─── page layout ─────────────────────┐
│ │
│ ┌── block "content" ──┐ │
│ │ │ │
│ │ ┌ block ┐ ┌ block ┐ │ │
│ │ │"left" │ │"right"│ │ │
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
│ │ └───────┘ └───────┘ │ │
│ └─────────────────────┘ │
│ │
└─────────────────────────────────────┘
如果没有 embed
标签,您有两种方法来设计您的模板
- 创建两个“中间”基础模板,它们扩展了主布局模板:一个带有垂直堆叠的框,供“page_1”和“page_2”页面使用,另一个带有并排的框,供“page_3”和“page_4”页面使用。
- 将顶部/底部和左侧/右侧框的标记直接嵌入到每个页面模板中。
这两种解决方案都不能很好地扩展,因为它们各自都有一个主要的缺点
- 第一种解决方案对于这个简化的示例可能确实有效。但是想象一下我们添加一个侧边栏,它可能再次包含不同的、重复出现的内容结构。现在我们需要为内容结构和侧边栏结构的所有出现的组合创建中间基础模板...等等。
- 第二种解决方案涉及重复的公共代码及其所有负面后果:任何更改都涉及到查找和编辑结构的所有受影响副本,必须为每个副本验证正确性,副本可能会因粗心的修改而失去同步等。
在这种情况下,embed
标签就派上用场了。公共布局代码可以存在于单个基础模板中,而两种不同的内容结构,我们称之为“微型布局”,则放入单独的模板中,并在必要时嵌入。
页面模板 page_1.html.twig
1 2 3 4 5 6 7 8 9 10 11 12 13
{% extends "layout_skeleton.html.twig" %}
{% block content %}
{% embed "vertical_boxes_skeleton.html.twig" %}
{% block top %}
Some content for the top box
{% endblock %}
{% block bottom %}
Some content for the bottom box
{% endblock %}
{% endembed %}
{% endblock %}
这是 vertical_boxes_skeleton.html.twig
的代码
1 2 3 4 5 6 7 8 9 10 11
<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.html.twig
模板的目标是分解框的 HTML 标记。
embed
标签接受与 include
标签完全相同的参数
1 2 3 4 5 6 7 8 9 10 11
{% embed "base" with {'name': 'Fabien'} %}
...
{% endembed %}
{% embed "base" with {'name': 'Fabien'} only %}
...
{% endembed %}
{% embed "base" ignore missing %}
...
{% endembed %}
警告
由于嵌入式模板没有“名称”,如果您更改上下文(例如,如果您将 CSS/JavaScript 模板嵌入到 HTML 模板中),基于模板名称的自动转义策略将无法按预期工作。在这种情况下,请使用 autoescape
标签显式设置默认的自动转义策略。
另请参阅