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


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


29
2017-08-13 16:25


起源




答案:


何时使用继承:

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

何时使用包括:

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

另一种用法:

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

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

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

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

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

所以:

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


45
2017-08-23 14:31



“当然,要为页眉,页脚创建块...但这是错误的设计,如上所述。” - 如果它更符合您的设计或思维模式,我认为这不是“错误的”。但总的来说,你可能不得不使用 多 包括(标题+页脚至少)以模仿继承,这可能效率较低并增加了复杂性。 - Simon East


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

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

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

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

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

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

{% include 'header.html' %}

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

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

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


8
2017-08-14 08:08



“现在扩展给我的是使用来自父级的块!你没有包含的内容。”我有 - {%set title%}我的标题仅适用于此页面{%endset%}和{{ title}}。它是相同的功能,但在其他方向,唯一的区别是 - 在块我可以在块中设置默认内容但是当我包括时,要设置默认内容我必须使用条件。 - Isinlor
这是一个很好的具体例子。 - alexw


只需添加另一个混合选项,您可以考虑  同样。它允许您利用继承 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>

6
2018-02-18 22:35





这取决于你想要完成的事情。通过扩展视图,您将使用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.twig 和 contact.html.twig 仅包含这些特定部分的HTML。这两种观点都有所延伸 base.html.twig。这消除了代码重复。如果要对标题进行更改,只需在一个位置进行更改 - base.html.twig

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

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

希望这可以帮助!


3
2017-08-13 19:32



好的,但是只使用包含会更容易吗? Base.html.twig将是:Header.html.twig和Footer.html.twig和About.html.twig将如下所示:<code> include Header.html.twig包括PieceOfContent.html.twig about etc包括Footer。 html.twig </ code>我认为使用扩展没有任何好处。尽管如此,如果Base.html.twig看起来像这样:<code> Header特定内容块来自about,contact etc菜单 - 所有页面都相同另一块特定内容页脚</ code>那么我们将减少2个文件比仅使用包括 - 这就是全部? - Isinlor
在您网站的所有“网页”视图中包含header.html.twig和footer.html.twig是糟糕的编程。这些元素对您的网站来说很常见,因此它们只应包含在base.html.php中一次。想想你何时不想再包含header.html.twig,但想要包含someOtherHeader.html.twig。现在,您必须在视图中更改所有包含。你最好把它放在base.html.twig中。一般的经验法则是在您的网站上重复的任何HTML都属于base.html.twig - Steven Mercatante
此外,您的示例有一个很大的问题:您包括页眉和页脚两次。一旦进入base.html.twig,再次进入about.html.twig。你想要about.html.twig来包含 只要 与该页面相关的HTML。页眉和页脚与about页面完全分开,您的设置应该反映出来。 - Steven Mercatante
“想想你何时不想再包含header.html.twig,但想要包含someOtherHeader.html.twig。”如果我不再需要扩展Base.html.twig但是someOtherBase.html.twig,也会发生同样的情况。并且包括两次 - 我记住了页眉和页脚而不是基础,而不是基础;)。 - Isinlor
布局(base.html.twig)旨在包含您网站的常见HTML,因此其他视图只需要担心显示特定内容。这不是延伸与包含的问题,而是一个问题,即何时何地使用它们。如果不使用布局,您将很快意识到HTML可以在网站范围内更新。阅读有关装饰器模式和Symfony 1模板的更多信息以获得更好的想法。 - Steven Mercatante


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

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

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


1
2017-08-14 02:53