2011-08-13 22 views
27

为什么Twig文档建议使用扩展而不是包括? Symfony 2的文档说是因为“在Symfony2中,我们喜欢以不同的方式思考这个问题:一个模板可以被另一个模板所装饰。”但仅此而已。这只是作者的奇思妙想或更多?感谢帮助。扩展或包含 - Twig中哪种更好?

回答

42

当使用继承:

你有50页共享相同的布局 - 创建layout.twig作为父母,并且每一页扩展了layout.twig。所以父母是通用的,孩子是特定的。

当使用包括:

出了50页的,也有共享的HTML块6页 - 创建一个共享chunk.twig并将其包含在那些6页。

另一个用途:

您注意到layout.twig是有点混乱,你想模块化,所以拆分sidebar.twig到一个单独的文件,并将其包含在layout.twig。

您可以使用包括继承用例:

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

你可以使用继承了包括用例:

当然,在父layout.twig共享块创建一个空块,并创建一个第二级子布局与-块。将layout.twig扩展并填充块块,然后在上面的示例中共享该块的6个页面可以扩展layout-with-chunk.twig而不是layout.twig。但是这又是错误的设计,因为块块不被所有的孩子共享,并且不应该进入基础父项。另外你已经混淆了继承树。

所以:

如上所述 - 它的设计不是编程的问题。这不是关于:我可以使用不同的编程技术来获得相同的结果,关于哪种用法是更好的设计。

+0

“当然,为页眉,页脚创建块......但这是上面解释的错误设计。” - 如果它更符合你的设计或思维,我认为这不是“错误”。但一般情况下,您可能必须使用* multiple * includes(至少包含页眉+页脚)来模仿继承,这可能会降低效率并增加复杂性。 –

3

这取决于你想完成什么。通过扩展视图,您正在使用装饰模式。如果你熟悉Symfony 1,这与输出$ sf_content的layout.php文件是一样的。当你想在整个项目中使用一个常用的html'shell'时,你使用这个方法。

另一方面,包含视图可让您在另一个视图中插入一个视图。

假设您有一个包含'about'和'contact'页面的个人网站。您将有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

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

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

希望这会有所帮助!

+0

OK,但不会是更容易使用只包含? Base.html.twig将是: Header.html.twig和Footer.html.twig 而About.html.twig将如下所示: include Header.html.twig include PieceOfContent.html.twig about etc include Footer.html.twig 我没有看到使用扩展的好处。 虽然,如果Base.html.twig看起来像这样: Header Block of specific content from about, contact etc Menu - the same for all pages Another block of specific content Footer 然后,我们将有2个文件比只使用包括 - 这是全部? – Isinlor

+0

在网站的所有'网页'视图中包含header.html.twig和footer.html.twig都是糟糕的编程。这些元素对于您的网站来说很常见,所以它们应该只包含一次,在base.html.php中。想想什么时候不再需要包含header.html.twig,但想包含一些OtherHeader.html.twig。现在你必须改变你的观点中的所有内容。你最好把它放在base.html.twig中。一般的经验法则是任何在您的网站上重复使用的HTML都属于base.html.twig –

+0

另外,您的示例有一个很大的问题:您需要两次包含页眉和页脚。一旦进入base.html.twig,然后再次进入about.html.twig。您希望about.html.twig包含* ONLY *与该页面相关的HTML。页眉和页脚完全独立于关于页面,并且您的设置应该反映出这一点。 –

1

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

“包含”不够灵活,您从基本模板开始,到about.htm视图工作,并且无法在不同文件中处理常见的内容块。

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

7

我喜欢武器的答案,但我认为你错过了什么,他说。包含和扩展是不同的事情:如果扩展,您可以更改父项,使用不包含的项。

E.g. 我致以基地布局,像这样:

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

什么扩展现在给我,是从父使用块!你没有包含这个。现在你可以做一个标题专门为每一页:

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

现在,包括给你更多的刚性和固定的HTML,e.g:

{% include 'header.html' %} 

,并在最可能entitiy repitition,例如表行:

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

所以你建立你的布局与包括和你扩展你的基地布局,以确保自己的网站符合指定的设计。

+0

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

+0

这是一个很好的具体例子。 – alexw

5

只是为了增加另一个混合选项,你可能会考虑embed。它可以让你利用从extends继承,但也允许多次重用,如include呢。

微不足道的示例:

“partials/titleize。小枝“:

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

”一些-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>