twig - 将函数传递到模板中更新 2015/5/14
目前,我将函数放在一个类中,并将该类的实例传递到模板中,并将所需的函数作为类方法调用。
{{ unneededclass.blah() }}
我需要像下面一样
{{ blah() }}
可能吗?
目前,我将函数放在一个类中,并将该类的实例传递到模板中,并将所需的函数作为类方法调用。
{{ unneededclass.blah() }}
我需要像下面一样
{{ blah() }}
可能吗?
评论者指出,我大多错了。如果你真的需要一个函数,而不是一个过滤器或宏,你可以按照Twig文档中的建议去做:
$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” 的
字符串。
在vanilla PHP中,当您使用这样的变量函数时(尝试像使用函数一样的字符串变量),它(或多或少)执行该函数的查找,然后调用它。您没有传递函数,只是传递了它的名称。
问题是,你不可能将一个函数传递到一个模板中,因为PHP唯一的机制是通过name-string,一旦进入模板,这个名字就不再是一个函数名称,而只是一个字符串。
有点冗长,但我希望这有帮助!
如果您想要更多文档,请点击此处查看官方文档。
虽然你不能直接调用PHP,但树枝是可扩展的。您可以添加可调用的过滤器,以便可以应用于传递给模板的 PHP 函数。
namespace My\Twig\Extension;
class LambdaFilter extends \Twig_Extension {
public function getName() {
return 'lambda_filter';
}
public function getFilters() {
return array(
new \Twig_SimpleFilter('call', array($this, 'doCall'))
);
}
public function doCall() {
$arguments = func_get_args();
$callable = array_shift($arguments);
if(!is_callable($callable)) {
throw new InvalidArgumentException();
}
return call_user_func_array($callable, $arguments);
}
}
现在,如果将变量传递给模板,则可以执行 .您甚至可以执行更高阶的函数,并且始终可以在过滤器中执行更多操作,例如接受数组作为参数等。my_func
my_func|call(arg1, arg2)
"array_filter"|call(my_array, my_func)