【问题标题】:Extending or including - what is better in Twig?扩展或包含 - Twig 中什么更好?
【发布时间】:2011-10-26 11:24:57
【问题描述】:

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

【问题讨论】:

    标签: php symfony twig template-engine


    【解决方案1】:

    何时使用继承:

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

    何时使用包括:

    在 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。但这又是错误的设计,因为块不被所有子共享,不应该进入基础父。此外,您还弄乱了继承树。

    所以:

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

    【讨论】:

    • “当然,为页眉、页脚创建块……但如上所述,这是错误的设计。” ——如果它更适合你的设计或心态,我认为它不是“错误的”。但一般来说,您可能不得不使用 multiple 包含(至少是页眉+页脚)来模拟继承,这可能效率较低并增加了复杂性。
    【解决方案2】:

    我喜欢 Arms 的回答,但我认为你错过了他所说的话。包含和扩展是不同的东西:如果扩展,则可以更改父级,而包含则不能。

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

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

    现在扩展给我的是使用父级的块!你没有包含的那个。现在你可以例如为每一页专门设置一个标题:

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

    现在,包括为您提供更严格和固定的 html,例如:

    {% include 'header.html' %}
    

    最多可能是实体重复,例如表格行:

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

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

    【讨论】:

    • "现在扩展给我的是使用父级的块!你没有包含的那个。" 我有 - {% set title %}我的标题只是为了这个页面{% endset %} 和 {{ title }}。这是相同的功能,但在其他方面,唯一的区别是 - 在块中我可以在块中设置默认内容但是当我包含时,要设置默认内容我必须使用条件。
    【解决方案3】:

    只是为了添加另一个混合选项,您也可以考虑embed。它允许您利用从 extends 的继承,但也允许像 include 那样多次重用。

    简单的例子:

    “partials/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>
    

    【讨论】:

      【解决方案4】:

      这取决于您要完成的工作。通过扩展视图,您正在使用装饰器模式。如果你熟悉 Symfony 1,这与你的 layout.php 文件输出 $sf_content 是一样的。当您有一个想要在整个项目中使用的通用 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。

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

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

      希望这会有所帮助!

      【讨论】:

      • 好的,但是只包含会不会更容易使用? 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 - 所有页面都相同 另一个特定内容块 Footer 那么我们将少 2 个文件而不是仅使用包含 - 仅此而已?
      • 在您网站的所有“页面”视图中包含 header.html.twig 和 footer.html.twig 是糟糕的编程。这些元素对您的站点来说是通用的,因此它们应该只包含一次,在 base.html.php 中。考虑一下您何时不想包含 header.html.twig,但想要包含 someOtherHeader.html.twig。现在您必须更改视图中的所有包含。你最好把它放在 base.html.twig 中。一般的经验法则是在您的网站上重复的任何 HTML 都属于 base.html.twig
      • 另外,您的示例有一个大问题:您包含页眉和页脚两次。一次在 base.html.twig 中,然后再次在 about.html.twig 中。您希望 about.html.twig 包含 ONLY 与该页面相关的 HTML。页眉和页脚与 about 页面完全分开,您的设置应该反映这一点。
      • "想想什么时候你不再想包含 header.html.twig,而是想包含 someOtherHeader.html.twig。"如果我不再想要扩展 Base.html.twig 而是 someOtherBase.html.twig,也会发生同样的情况。关于包括两次 - 我想到的是页眉和页脚而不是基数,而不是基数;)。
      • 布局 (base.html.twig) 旨在包含您网站的通用 HTML,因此其他视图只需担心显示特定内容。这不是扩展与包含的问题,而是何时何地使用它们的问题。如果您不使用布局,您将很快意识到在站点范围内更新 HTML 是多么痛苦。阅读有关装饰器模式和 Symfony 1 模板的更多信息,以获得更好的想法。
      【解决方案5】:

      Twig 扩展与 include 不同,而且功能强大得多。尝试将扩展视为与您考虑包含的方式相反的方式。通过扩展,您可以从最终视图(即 about.htm)开始并向后工作,添加在网站上制作页面所需的图层。在每个级别,通过扩展内容块覆盖或添加到该块的父内容。

      “包含”没有那么灵活,您从基本模板开始,然后一直到 about.htm 视图,您无法处理不同文件中的通用内容块。

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

      【讨论】:

        猜你喜欢
        • 2016-08-11
        • 1970-01-01
        • 2013-01-19
        • 2023-04-05
        • 2012-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-21
        相关资源
        最近更新 更多