扩展或包含——Twig 中哪个更好?
为什么 Twig 文档建议使用扩展而不是包含? Symfony 2 文档说,因为“在 Symfony2 中,我们喜欢以不同的方式思考这个问题:一个模板可以被另一个模板装饰。”但仅此而已。这只是作者的心血来潮还是另有原因?感谢您的帮助。
Why Twig documentation recommends to use extending rather than including? Symfony 2 documentation says because "In Symfony2, we like to think about this problem differently: a template can be decorated by another one." but nothing more. It's just author's whim or something more? Thanks for help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
何时使用继承:
您有 50 个页面共享相同的布局 - 您创建一个layout.twig 作为父级,每个页面都扩展该layout.twig。所以父级是通用的,子级是特定的。
何时使用 include:
在 50 个页面中,有 6 个页面共享一块 HTML - 您创建一个共享块.twig 并将其包含在这 6 个页面中。
另一种用法:
您注意到您的layout.twig有点混乱,并且您想将其模块化,因此您将sidebar.twig拆分为一个单独的文件并将其包含在layout.twig中。
您可以将 include 用于继承用例吗:
当然,为页眉、页脚以及您拥有的内容创建块,并在 50 个页面中的每一页中使用 include。但这是错误的设计,如上所述。
您可以在包含用例中使用继承吗:
当然,为父layout.twig中的共享块创建一个空块,并创建一个扩展的第二级子layout-with-chunk.twig layout.twig 并填充 chunk 块,上面示例中共享 chunk 的 6 个页面可以扩展 layout-with-chunk.twig 而不是 layout.twig。但这又是错误的设计,因为块块并非由所有子级共享,并且不应进入基本父级。另外,你还弄乱了继承树。
所以:
如上所述 - 这是设计问题而不是可编程性。这不是关于:我可以使用不同的编程技术实现相同的结果,而是关于哪种用法是更好的设计。
When to use inheritance:
You have 50 pages sharing the same layout - you create a layout.twig as a parent, and each page extends that layout.twig. So the parent is the generic and the child is the specific.
When to use include:
Out of the 50 pages, there are 6 pages that share a chunk of HTML - you create a shared-chunk.twig and include it in those 6 pages.
Another usage:
You notice that your layout.twig is bit cluttered and you would like to modularize it, so you split sidebar.twig into a separate file and include it in layout.twig.
Can you use include for the inheritance use-case:
Sure, create chunks for header, footer and what have you, and use includes in each of the 50 pages. But that's wrong design as explained above.
Can you use inheritance for the include use-case:
Sure, create an empty block for the shared chunk in the parent layout.twig, and create a second level child layout-with-chunk.twig that extends layout.twig and fills in the chunk block, and the 6 pages in the above example that share the chunk can then extend layout-with-chunk.twig instead of layout.twig. But this again is wrong design because the chunk block is not shared by all children and shouldn't go into the base parent. Plus you have cluttered the inheritance tree.
So:
As explained above - it's a matter of design not programmability. It's not about: I can achieve this same result using a different programming technique, its about which usage is better design.
我喜欢阿姆斯的回答,但我想你错过了他说的话。包含和扩展是不同的事情:如果扩展,则可以更改父级,而包含则不能。
例如
我扩展了我的基本布局,如下所示:
现在扩展给我的是使用父级的块!你没有包含在内。现在,您可以例如为每个页面专门制作一个标题:
现在,包括为您提供更严格和固定的html,例如:
最多可能是实体重复,例如表格行:
因此您可以使用包含构建您的布局,并扩展您的基本布局确保您的网站遵循指定的设计。
I liked Arms answer, but I think you missed what he said. Include and extend are different things: if you extend, you can change the parent, with an include you can not.
E.g.
I extend my base layout, like so:
What extending give me now, is to use the blocks from the parent! You don't have that with an include. Now you can e.g. make a title specifically for every page:
Now, including gives you more rigid and fixed html, e.g:
and at most maybe entitiy repitition, e.g. table rows:
So you build your layouts with includes, and you extend your base layouts to make sure your site follows the designated design.
只是为了添加另一个混合选项,您可以考虑 嵌入 作为出色地。它允许您利用
extends
的继承,但也允许像include
那样多次重用。简单的例子:
"partials/titleize.twig":
"some-template.twig" 将使用
embed
继承它:
Just to add another, hybrid, option into the mix, you might consider embed as well. It lets you leverage the inheritance from
extends
but also allows multiple reuses likeinclude
does.Trivial example:
"partials/titleize.twig":
"some-template.twig" will inherit from it using
embed
:Renders
这取决于您想要实现的目标。通过扩展视图,您可以使用装饰器模式。如果您熟悉 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
。这些文档实际上并不建议扩展包括,它们是两种独立的方法,应该用于特定目的。
希望这有帮助!
It depends on what you're trying to accomplish. By extending a view, you're using the Decorator pattern. If you're familiar with Symfony 1, this is the same as having your layout.php file which outputs $sf_content. You use this method when you have a common html 'shell' you want to use across the project.
Including a view on the other hand lets you inject one view in another.
Let's say you have a personal site with 'about' and 'contact' pages. You would have 3 views:
base.html.twig
about.html.twig
contact.html.twig
base.html.twig
contains the common HTML that your site uses across the board. This could include your header, navigation, footer etc (all the stuff that doesn't/shouldn't change across pages.)about.html.twig
andcontact.html.twig
contain ONLY the HTML for those specific sections. Both of these views extendbase.html.twig
. This eliminates code duplication. If you want to make a change to the header, you just need to make the change in one place -base.html.twig
.Now let's say you have some other piece of content you want to display on the 'about' and 'contact' pages (but not necessarily on other pages) - you could create a separate view for this and include it within
about.html.twig
andcontact.html.twig
.The docs don't actually recommend extending over including, they're two separate methods that should be used for specific purposes.
Hope this helps!
Twig 扩展是不同的,并且比包含更强大。尝试将扩展视为与您思考包含的方式相反的方式。通过扩展,您可以从最终视图(即 about.htm)开始并向后工作,添加在网站上制作页面所需的图层。在每个级别,通过扩展,内容块会覆盖或添加到该块的父内容。
“包含”不太灵活,您从基本模板开始,然后转到 about.htm 视图,并且无法使用不同文件中的公共内容块。
查看有关三级继承的内容,这是一种常见的扩展模式: http://symfony.com/doc/current/book/templated.html#三级继承
Twig extension is different and far more powerful than include. Try thinking about extension as coming at it from the opposite of the way you are thinking about include. With extension you can start with the end view (i.e. about.htm) and working backwards, adding the layers that you need to make the page on the site. At each level, with extension the blocks of content either overwrite or add to the parent content for that block.
"Include" isn't as flexible, you are starting with the base template and work your way out to the about.htm view, and you can't work with common blocks of content across the different files.
Check out this bit on three-level inheritance, which is a common extension pattern: http://symfony.com/doc/current/book/templating.html#three-level-inheritance