2015 年 5 月 14 日更新
评论者指出,我大多是错的。如果你真的需要一个函数,而不是一个过滤器或宏,你可以使用suggested in the Twig docs:
$twig = new Twig_Environment($loader);
$function = new Twig_SimpleFunction('blah', function () {
// ...
});
$twig->addFunction($function);
并使用喜欢
{{ blah() }}
简而言之,不,这是不可能的。
但是,希望并没有消失!
过滤器
如果你的这个函数blah() 是为了修改一个现有的变量,那么它就是一个过滤器。
一个例子:
//in your PHP
function format_date($date_string,$format_string) {
return date($format_string,strtotime($date_string));
}
$twig_env->addFilter('format_date',new Twig_Filter_Function('format_date'));
{# in your template #}
{{ some_date|format_date('n/j/Y') }}
(第一个参数是您要过滤的变量,第二个是通过正常方式提供的)
宏
如您在上面指出的那样,如果您的函数只是输出 HTML,那么它是一个很好的宏候选对象。
一个例子:
{# in your template #}
{% macro say_hello() %}
<p>Oh! Hello, world!</p>
{% endmacro %}
{# ... later on ... #}
{{ _self.say_hello() }}
或者带参数:
{% macro input(name,value,type) %}
<input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value }}">
{% endmacro %}
{{ _self.input('phone_number','867-5309') }}
{{ _self.input('subscribe','yes','checkbox') }}
为什么?
要记住的是,就 MVC 而言,Twig 模板代表一个视图。这意味着它们在环境方面是孤立的,只能表示您通过$template->render() 方法中传递的数据数组传递它们的上下文。
这是一件好事,因为它将您的演示文稿与您的逻辑和数据分离。如果你可以任意调用函数,那么你会突然增加耦合,这是一个坏的事情。
另一个原因是 PHP 处理回调的方式。想想你必须如何将该函数传递到你的模板中......大概是这样的:
function blah() {
return "<p>Oh! Hello, world!</p>";
}
$template = $twig_env->loadTemplate('template.html');
echo $template->render(array('blah'=>'blah'));
在您的模板中,上下文变量blah 现在只是一个包含'blah' 的字符串。
在原生 PHP 中,当您使用像这样的变量函数(尝试使用像函数一样的字符串变量)时,它(或多或少)会执行对该函数的查找,然后调用它。您没有传递函数,只是传递了它的名称。
问题是,你不可能将函数传递给模板,因为 PHP 这样做的唯一机制是通过名称字符串,一旦进入模板,该名称就不再是函数名称,而只是一个字符串。
有点啰嗦,但希望对你有帮助!
如果您需要更多文档,官方文档是here。