扩展或包括 - 在Twig中哪个更好?

时间:2011-08-13 16:25:13

标签: php symfony twig template-engine

为什么Twig文档建议使用扩展而不是包含? Symfony 2文档说因为“在Symfony2中,我们喜欢以不同的方式思考这个问题:模板可以用另一个模板来装饰。”但仅此而已。这只是作者的心血来潮还是其他什么?谢谢你的帮助。

5 个答案:

答案 0 :(得分:46)

何时使用继承:

您有50个页面共享相同的布局 - 您将layout.twig创建为父级,并且每个页面都扩展该layout.twig。所以父母是通用的,孩子是特定的。

何时使用include:

在50个页面中,共有6个页面共享一大块HTML - 您创建了一个shared-chunk.twig并将其包含在这6个页面中。

另一种用法:

您注意到layout.twig有点杂乱,您希望将其模块化,因此您将sidebar.twig拆分为单独的文件并将其包含在layout.twig中。

您可以使用include作为继承用例:

当然,为页眉,页脚和你有什么创建块,并在50页中的每一页中使用包含。但如上所述,这是错误的设计。

您可以使用包含用例的继承:

当然,在父layout.twig中为共享块创建一个空块,并创建一个扩展layout.twig并填充块块的第二级子layout-with-chunk.twig,以及6个页面上面共享块的示例可以扩展layout-with-chunk.twig而不是layout.twig。但这又是错误的设计,因为块块不是所有子节点共享的,不应该进入基本父节点。另外,你把继承树弄得乱七八糟。

所以:

如上所述 - 这是设计而非可编程性的问题。它不是关于:我可以使用不同的编程技术实现相同的结果,它的用法是更好的设计。

答案 1 :(得分:8)

我喜欢阿姆斯回答,但我想你错过了他说的话。包含和扩展是不同的东西:如果你扩展,你可以改变父,用你不能的包含。

E.g。 我扩展了我的基本布局,如下所示:

{% extends "layout/default.html" %}

现在扩展给我的是使用父母的块!你没有包括。现在你可以,例如专门为每个页面制作一个标题:

{% block title %}My title just for this page{% endblock %}

现在,包括给你更严格和固定的html,例如:

{% include 'header.html' %}

并且最多可能有权重复,例如表格行:

{% include 'foo' with {'foo': 'bar'} %}

因此,您使用包含构建布局,并扩展基本布局以确保您的网站遵循指定的设计。

答案 2 :(得分:6)

只需添加另一个混合选项,您也可以考虑使用embed。它允许您利用extends的继承,但也允许include之类的多次重用。

琐碎的例子:

“谐音/ titleize.twig”:

<h2 class="title">{% block title %}Default Title{% endblock %}</h2>

“some-template.twig”将使用embed继承它:

{% embed "partials/titleize.twig" %}
    {% block title %}Section 1{% endblock %}
{% endembed %}

...

{% embed "partials/titleize.twig" %}
    {% block title %}Section 2{% endblock %}
{% endembed %}

渲染

<h2 class="title">Section 1</h2>
...
<h2 class="title">Section 2</h2>

答案 3 :(得分:4)

这取决于你想要完成的事情。通过扩展视图,您将使用Decorator模式。如果你熟悉Symfony 1,这与你输出$ sf_content的layout.php文件是一样的。如果要在项目中使用通用的html“shell”,则可以使用此方法。

另一方面,包含视图可以将一个视图注入另一个视图。

假设您有一个包含“关于”和“联系”页面的个人网站。你有3个意见: base.html.twig
about.html.twig
contact.html.twig

base.html.twig包含您的网站全面使用的常见HTML。这可能包括你的标题,导航,页脚等(所有那些不会/不应该跨页面改变的东西。)

about.html.twigcontact.html.twig仅包含这些特定部分的HTML。这两个视图都扩展了base.html.twig。这消除了代码重复。如果您想对标题进行更改,只需在一个位置进行更改 - base.html.twig

现在假设您要在“约”和“联系”页面上显示其他内容(但不一定在其他页面上) - 您可以为此创建单独的视图并将其包含在{{ 1}}和about.html.twig

文档实际上并不建议扩展包括,它们是两个应该用于特定目的的独立方法。

希望这有帮助!

答案 4 :(得分:1)

Twig扩展是不同的,远比include更强大。尝试将扩展视为与您考虑包含的方式相反的方式。通过扩展,您可以从结束视图(即about.htm)开始,然后向后工作,添加在网站上创建页面所需的图层。在每个级别,通过扩展,内容块可以覆盖或添加到该块的父内容。

“包含”不是那么灵活,您从基本模板开始并逐步运行到about.htm视图,并且您无法使用不同文件中的公共内容块。

在三级继承上查看此位,这是一种常见的扩展模式:http://symfony.com/doc/current/book/templating.html#three-level-inheritance