包含、扩展、使用、宏、嵌入在 Twig 中的区别

2022-01-22 00:00:00 php symfony twig silex

useinclude在Twig中有什么区别?

文档:

<块引用>

包括

include 语句包含一个模板并将该模板的渲染内容返回到当前模板中:

{% include 'header.html' %}身体在这里...{% 包括'footer.html' %}

使用

use 语句告诉 Twig 将 blocks.html 中定义的块导入当前模板(类似于宏,但用于块):

blocks.html

{% block sidebar %}{% endblock %}

main.html

{% extends "base.html" %}{% 使用blocks.html"%}{% 块标题 %}{% endblock %}{% 块内容 %}{% endblock %}

<小时>

可能的答案:

我认为 this 应该可以解释差异:

<块引用>

include 是从外部文件中获取所有代码并导入在呼叫的正确位置进入您的实际文件.

use 完全不同,因为它解析链接文件以查找特定的代码部分,然后用在您当前的文件中,与在此外部文件中找到的名称相同文件.

include 就像去找到这个文件并在这里​​用我的页面呈现它".

use 是解析这个其他文件以找到要使用的块定义我自己的定义在这里.

如果 use 命令找不到与任务匹配的内容,则不显示任何内容完全来自这个文件.

<小时>

问题

解释正确吗?这种差异还有其他解释吗?

解决方案

几个月后,我将发布一个答案,以供进一步参考此问题.我还为 extends & 添加了一些描述.导入 & &embed 以获得更多权限:

Twig 中有各种类型的继承和代码重用:

<小时>

包括

主要目标:代码重用

用例:使用header.html.twig &footer.html.twigbase.html.twig 内.

header.html.twig

footer.html.twig

<footer><div>版权所有</div></页脚>

base.html.twig

{% include 'header.html.twig' %}<main>{% block main %}{% endblock %}</main>{% 包括 'footer.html.twig' %}

<小时>

扩展

主要目标:垂直重用

用例:在homepage.html.twig中扩展base.html.twig &about.html.twig.

base.html.twig

{% include 'header.html.twig' %}<main>{% block main %}{% endblock %}</main>{% 包括 'footer.html.twig' %}

homepage.html.twig

{% 扩展 'base.html.twig' %}{% 块主 %}<p>主页</p>{% 端块 %}

about.html.twig

{% 扩展 'base.html.twig' %}{% 块主 %}<p>关于页面</p>{% 端块 %}

<小时>

使用

主要目标:水平重用

用例: sidebar.html.twig in single.product.html.twig &single.service.html.twig.

sidebar.html.twig

{% block sidebar %}<aside>这是sidebar</aside>{% endblock %}

single.product.html.twig

{% extends 'product.layout.html.twig' %}{% 使用 'sidebar.html.twig' %}{% block main %}<main>产品页面</main>{% endblock %}

single.service.html.twig

{% extends 'service.layout.html.twig' %}{% 使用 'sidebar.html.twig' %}{% block main %}<main>服务页面</main>{% endblock %}

注意事项:

  1. 类似于宏,但用于块.
  2. use 标记仅在不扩展另一个模板、未定义宏且正文为空时才导入模板.

<小时>

主要目标:带有变量的可重用标记

用例:获取一些变量并输出一些标记的函数.

form.html.twig

{% 宏输入(名称、值、类型)%}<input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" }}"/>{% endmacro %}

profile.service.html.twig

{% import "form.html.twig" as form %}<form action="/login" method="post"><div>{{ form.input('username') }}</div><div>{{ form.input('password') }}</div><div>{{ form.input('submit', 'Submit', 'submit') }}</div></表格>

<小时>

嵌入

主要目标:块覆盖

用例:在product.table.html.twig中嵌入pagination.html.twig &service.table.html.twig.

pagination.html.twig

<div id="分页"><div>{% block first %}{% endblock %}</div>{% for i in (min + 1)..(max - 1) %}<div>{{ i }}</div>{% endfor %}<div>{% block last %}{% endblock %}</div></div>

product.table.html.twig

{% set min, max = 1, products.itemPerPage %}{% 嵌入'pagination.html.twig' %}{% block first %}第一个产品页面{% endblock %}{% block last %}最后一个产品页{% endblock %}{% 嵌入 %}

service.table.html.twig

{% set min, max = 1, services.itemPerPage %}{% 嵌入'pagination.html.twig' %}{% block first %}第一个服务页面{% endblock %}{% block last %}最后一个服务页{% endblock %}{% 嵌入 %}

请注意嵌入文件 (pagination.html.twig) 可以访问当前上下文 (min, max 变量).

您也可以将额外的变量传递给嵌入文件:

pagination.html.twig

<p>{{ count }} 个项目</p>

<div>{% block first %}{% endblock %}</div>{% for i in (min + 1)..(max - 1) %}<div>{{ i }}</div>{% endfor %}<div>{% block last %}{% endblock %}</div></div>

product.table.html.twig

{% set min, max = 1, products|length %}{% embed 'pagination.html.twig' with {'count': products|length } %}{% block first %}第一个产品页面{% endblock %}{% block last %}最后一个产品页{% endblock %}{% 嵌入 %}

注意:

它同时具有使用 &包含在一起.

What is the difference between use and include in Twig?

Documentation:

include

The include statement includes a template and returns the rendered content of that template into the current one:

{% include 'header.html' %}
Body here...
{% include 'footer.html' %}

use

The use statement tells Twig to import the blocks defined in blocks.html into the current template (it's like macros, but for blocks):

blocks.html

{% block sidebar %}{% endblock %}

main.html

{% extends "base.html" %}
{% use "blocks.html" %}
{% block title %}{% endblock %}
{% block content %}{% endblock %}


Possible answer:

I think this should explain the difference:

include is to get all the code from an external file and import it into your actual file at the right location of the call.

use is completely different as it parses the linked file to find a particular section of code and then overwrites the blocks with the same name, in your current file, with the one found in this external file.

include is like "go find this file and render it with my page here".

use is "parse this other file to find block definitions to use instead of my owns defined here".

If use command finds nothing matching the task, nothing is displayed at all from this file.


Question

is the explanation correct? are there any other explanations to this difference?

解决方案

After months, I am posting an answer for any further reference to this question. I also added some description for extends & import & macro & embed for more clearance:

There are various types of inheritance and code reuse in Twig:


Include

Main Goal: Code Reuse

Use Case: Using header.html.twig & footer.html.twig inside base.html.twig.

header.html.twig

<nav>
   <div>Homepage</div>
   <div>About</div>
</nav>

footer.html.twig

<footer>
   <div>Copyright</div>
</footer>

base.html.twig

{% include 'header.html.twig' %}
<main>{% block main %}{% endblock %}</main>
{% include 'footer.html.twig' %}


Extends

Main Goal: Vertical Reuse

Use Case: Extending base.html.twig inside homepage.html.twig & about.html.twig.

base.html.twig

{% include 'header.html.twig' %}
<main>{% block main %}{% endblock %}</main>
{% include 'footer.html.twig' %}

homepage.html.twig

{% extends 'base.html.twig' %}

{% block main %}
<p>Homepage</p>
{% endblock %}

about.html.twig

{% extends 'base.html.twig' %}

{% block main %}
<p>About page</p>
{% endblock %}


Use

Main Goal: Horizontal Reuse

Use Case: sidebar.html.twig in single.product.html.twig & single.service.html.twig.

sidebar.html.twig

{% block sidebar %}<aside>This is sidebar</aside>{% endblock %}

single.product.html.twig

{% extends 'product.layout.html.twig' %}

{% use 'sidebar.html.twig' %}

{% block main %}<main>Product page</main>{% endblock %}

single.service.html.twig

{% extends 'service.layout.html.twig' %}

{% use 'sidebar.html.twig' %}

{% block main %}<main>Service page</main>{% endblock %}

Notes:

  1. It's like macros, but for blocks.
  2. The use tag only imports a template if it does not extend another template, if it does not define macros, and if the body is empty.


Macro

Main Goal: Reusable Markup with Variables

Use Case: A function which gets some variables and outputs some markup.

form.html.twig

{% macro input(name, value, type) %}
    <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" }}" />
{% endmacro %}

profile.service.html.twig

{% import "form.html.twig" as form %}

<form action="/login" method="post">
    <div>{{ form.input('username') }}</div>
    <div>{{ form.input('password') }}</div>
    <div>{{ form.input('submit', 'Submit', 'submit') }}</div>
</form>


Embed

Main Goal: Block Overriding

Use Case: Embedding pagination.html.twig in product.table.html.twig & service.table.html.twig.

pagination.html.twig

<div id="pagination">
    <div>{% block first %}{% endblock %}</div>
    {% for i in (min + 1)..(max - 1) %}
        <div>{{ i }}</div>
    {% endfor %}
    <div>{% block last %}{% endblock %}</div>
</div>

product.table.html.twig

{% set min, max = 1, products.itemPerPage %}

{% embed 'pagination.html.twig' %}
    {% block first %}First Product Page{% endblock %}
    {% block last %}Last Product Page{% endblock %}
{% endembed %}

service.table.html.twig

{% set min, max = 1, services.itemPerPage %}

{% embed 'pagination.html.twig' %}
    {% block first %}First Service Page{% endblock %}
    {% block last %}Last Service Page{% endblock %}
{% endembed %}

Please note that embedded file (pagination.html.twig) has access to the current context (min, max variables).

Also you may pass extra variables to the embedded file:

pagination.html.twig

<p>{{ count }} items</p>
<div>
    <div>{% block first %}{% endblock %}</div>
    {% for i in (min + 1)..(max - 1) %}
        <div>{{ i }}</div>
    {% endfor %}
    <div>{% block last %}{% endblock %}</div>
</div>

product.table.html.twig

{% set min, max = 1, products|length %}

{% embed 'pagination.html.twig' with {'count': products|length } %}
    {% block first %}First Product Page{% endblock %}
    {% block last %}Last Product Page{% endblock %}
{% endembed %}

Note:

It has functionality of both Use & Include together.

相关文章