macro

宏与常规编程语言中的函数相当。它们对于重用模板片段以避免重复使用非常有用。

宏是在常规模板中定义的。

想象一下有一个通用的helper模板,它定义了如何通过宏呈现HTML表单(称为 forms.html ):

1
2
3
4
5
6
7
{% macro input(name, value, type = "text", size = 20) %}
    <input type="{{ type }}" name="{{ name }}" value="{{ value|e }}" size="{{ size }}"/>
{% endmacro %}

{% macro textarea(name, value, rows = 10, cols = 40) %}
    <textarea name="{{ name }}" rows="{{ rows }}" cols="{{ cols }}">{{ value|e }}</textarea>
{% endmacro %}

每个宏参数都可以有一个默认值(这里 text 的默认值 type 如果电话中没有提供)。

宏与本机PHP函数的不同之处在于:

  • 宏的参数总是可选的。
  • 如果将额外的位置参数传递给宏,它们将以特殊 varargs 变量作为值列表。

但是与PHP函数一样,宏不能访问当前的模板变量。

小技巧

可以将整个上下文作为参数传递,方法是使用特殊 _context 变量。

导入宏

有两种方法可以导入宏。您可以通过导入包含本地变量的模板 import 标记)或仅从模板导入特定宏(通过 from 标签)。

要将模板中的所有宏导入到局部变量中,请使用 import 标签:

1
{% import "forms.html" as forms %}

以上 import 调用导入 forms.html 文件(只能包含宏或模板和某些宏),并将宏作为 forms 局部变量。

然后可以在 现在的 模板:

1
2
<p>{{ forms.input('username') }}</p>
<p>{{ forms.input('password', null, 'password') }}</p>

或者,您可以通过将名称从模板导入到当前命名空间中 from 标签:

1
2
3
4
{% from 'forms.html' import input as input_field, textarea %}

<p>{{ input_field('password', '', 'password') }}</p>
<p>{{ textarea('comment') }}</p>

小技巧

当宏的定义与模板中的定义不同时,它们不需要自动导入 _self 变量:

1
2
3
4
5
<p>{{ _self.input('password', '', 'password') }}</p>

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

宏范围界定

无论是否通过导入宏,作用域规则都是相同的 importfrom .

导入的宏总是 地方的 到当前模板。这意味着宏在当前模板中定义的所有块和其他宏中都可用,但在包含的模板或子模板中不可用;您需要显式地在每个模板中重新导入宏。

导入的宏在的主体中不可用 embed 标记,则需要显式地在标记内重新导入宏。

打电话时 importfrom 从A block 标记,则导入的宏仅在当前块中定义,它们将覆盖在模板级别定义的同名宏。

打电话时 importfrom 从A macro 标记,则导入的宏仅在当前宏中定义,它们将覆盖在模板级别定义的同名宏。

检查是否定义了宏

您可以检查是否通过 defined 测试:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{% import "macros.twig" as macros %}

{% from "macros.twig" import hello %}

{% if macros.hello is defined -%}
    OK
{% endif %}

{% if hello is defined -%}
    OK
{% endif %}

命名宏结束标记

Twig允许您将宏的名称放在结束标记之后,以提高可读性(名称位于 endmacro word必须与宏名称匹配):

1
2
3
{% macro input() %}
    ...
{% endmacro input %}