宏
宏与常规编程语言中的函数相当。它们对于重用模板片段以避免重复自身很有用。
宏在常规模板中定义。
想象一下,有一个通用助手模板,它定义了如何通过宏来渲染 HTML 表单(称为 forms.twig
)
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.twig" as forms %}
上面的 import
调用导入 forms.html.twig
文件(该文件可以仅包含宏,或者包含模板和一些宏),并将宏作为 forms
局部变量的属性导入。
然后可以在当前模板中随意调用宏
1 2 3 4
<p>{{ forms.input('username') }}</p>
<p>{{ forms.input('password', null, 'password') }}</p>
{# You can also use named arguments #}
<p>{{ forms.input(name: 'password', type: 'password') }}</p>
或者,您可以通过 from
标签将名称从模板导入到当前命名空间中
1 2 3 4 5
{% from 'forms.html.twig' import input as input_field, textarea %}
<p>{{ input_field('password', '', 'password') }}</p>
<p>{{ input_field(name: 'password', type: 'password') }}</p>
<p>{{ textarea('comment') }}</p>
注意
由于通过 from
导入的宏像函数一样被调用,请注意它们会遮蔽现有函数
1 2 3 4
{% from 'forms.html.twig' import input as include %}
{# include refers to the macro and not to the built-in "include" function #}
{{ include() }}
提示
当宏的使用和定义在同一模板中时,您无需导入宏,因为它们会自动在特殊的 _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 %}
宏作用域
无论您是通过 import
还是 from
导入宏,作用域规则都是相同的。
导入的宏始终是当前模板的本地宏。这意味着宏在当前模板中定义的所有块和其他宏中都可用,但在包含的模板或子模板中不可用;您需要在每个模板中显式重新导入宏。
导入的宏在 embed
标签的主体中不可用,您需要在标签内显式重新导入宏。
当从 block
标签调用 import
或 from
时,导入的宏仅在当前块中定义,并且它们会遮蔽在模板级别使用相同名称定义的宏。
检查宏是否已定义
您可以通过 defined
测试检查宏是否已定义
1 2 3 4 5 6 7 8 9 10 11
{% import "macros.html.twig" as macros %}
{% from "macros.html.twig" import hello %}
{% if macros.hello is defined -%}
OK
{% endif %}
{% if hello is defined -%}
OK
{% endif %}
命名宏结束标签
Twig 允许您将宏的名称放在结束标记之后,以提高可读性(endmacro
单词后面的名称必须与宏名称匹配)
1 2 3
{% macro input() %}
...
{% endmacro input %}