embed
¶
这个 embed
标记结合了 include 和 extends . 它允许您包含另一个模板的内容,就像 include
做。但它也允许您覆盖包含的模板中定义的任何块,例如在扩展模板时。
将嵌入式模板视为“微布局骨架”。
1 2 3 4 5 6 7 8 9 10 | {% 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
tag将模板继承的思想引入到内容片段的级别。虽然模板继承允许“文档骨架”(documentskeletons)由子模板填充,但是 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) │ │
│ │ │ │
│ │ │ │
│ └─────────────────────┘ │
│ │
└─────────────────────────────────────┘
|
有些页面(“foo”和“bar”)共享相同的内容结构-两个垂直堆叠的框:
1 2 3 4 5 6 7 8 9 10 11 12 | ┌─── page layout ─────────────────────┐
│ │
│ ┌── block "content" ──┐ │
│ │ ┌─ block "top" ───┐ │ │
│ │ │ │ │ │
│ │ └─────────────────┘ │ │
│ │ ┌─ block "bottom" ┐ │ │
│ │ │ │ │ │
│ │ └─────────────────┘ │ │
│ └─────────────────────┘ │
│ │
└─────────────────────────────────────┘
|
而其他页面(“boom”和“baz”)共享不同的内容结构-两个框并排:
1 2 3 4 5 6 7 8 9 10 11 12 | ┌─── page layout ─────────────────────┐
│ │
│ ┌── block "content" ──┐ │
│ │ │ │
│ │ ┌ block ┐ ┌ block ┐ │ │
│ │ │"left" │ │"right"│ │ │
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
│ │ └───────┘ └───────┘ │ │
│ └─────────────────────┘ │
│ │
└─────────────────────────────────────┘
|
没有 embed
标记,您有两种方法来设计模板:
- 创建两个扩展主布局模板的“中间”基础模板:一个具有垂直堆叠的框,供“foo”和“bar”页面使用,另一个具有用于“boom”和“baz”页面的并排框。
- 将顶部/底部和左/右框的标记直接嵌入到每个页面模板中。
这两种解决方案的扩展性不好,因为它们都有一个主要缺点:
- 对于这个简化的例子,第一个解决方案确实可行。但是假设我们添加了一个侧边栏,它可能再次包含不同的、重复出现的内容结构。现在我们需要为所有内容结构和侧边栏结构的组合创建中间基模板。。。等等。
- 第二种解决方案涉及到公共代码的复制及其所有负面后果:任何更改都涉及到查找和编辑结构的所有受影响副本,必须验证每个副本的正确性,副本可能因不小心的修改而失去同步等。
在这种情况下 embed
标签派上用场。通用的布局代码可以存在于一个基础模板中,两个不同的内容结构,我们称之为“微布局”进入单独的模板中,这些模板根据需要嵌入:
页面模板 foo.twig
:
1 2 3 4 5 6 7 8 9 10 11 12 13 | {% 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
:
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.twig
模板将分解出框的HTML标记。
这个 embed
标记的参数与 include
标签:
1 2 3 4 5 6 7 8 9 10 11 | {% embed "base" with {'foo': 'bar'} %}
...
{% endembed %}
{% embed "base" with {'foo': 'bar'} only %}
...
{% endembed %}
{% embed "base" ignore missing %}
...
{% endembed %}
|
警告
由于嵌入式模板没有“名称”,因此如果更改上下文(例如,如果将CSS/JavaScript模板嵌入HTML模板中),基于模板名称的自动转义策略将无法按预期工作。在这种情况下,使用 autoescape
标签。
参见