twig - 将函数传递给模板函数、模板、twig

2023-09-07 00:12:33 作者:我姓路却遇不到我爱的人

目前我将我的函数放在一个类中,并将这个类的一个实例传递给模板,并将我需要的函数作为类方法调用.

Currently I place my function in a class and pass an instance of this class into template and call my required function as a class method.

{{ unneededclass.blah() }}

我需要像下面那样做

{{ blah() }}

有可能吗?

推荐答案

2015 年 5 月 14 日更新

评论者指出,我大多是错的.如果你真的需要一个函数,而不是一个过滤器或宏,你可以这样做 在 Twig 文档中建议:

$twig = new Twig_Environment($loader);
$function = new Twig_SimpleFunction('blah', function () {
   // ...
});
$twig->addFunction($function);

并使用喜欢

{{ blah() }}

简而言之,不,这是不可能的.

buuctf 7 md5强碰撞 Twig模板 utf 8字符大小 变量动态调用函数

In short, no, this is not possible.

但是,希望并没有消失!

However, hope is not lost!

如果你的这个函数 blah() 是为了修改一个现有的变量,那么它就是一个过滤器.

If this function blah() of yours is meant to modify an existing variable, then it is a filter.

一个例子:

//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') }}

(第一个参数是您要过滤的变量,第二个是通过正常方式提供的)

(The first argument is the variable you are filtering, the second is supplied by normal means)

如您在上面指出的,如果您的函数只是输出 HTML,那么它是一个很好的宏候选对象.

If, as you have indicated above, your function simply outputs HTML, then it is a good candidate for a macro.

一个例子:

{# 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() 中传递的数据数组传递它们的 context方法.

Why?

The thing to remember is that Twig templates represent a view, in terms of MVC. This means they are isolated in terms of their environment, and can only represent the context you pass them via the data array you pass in the $template->render() method.

这是一件好事,因为它将您的演示文稿与您的逻辑和数据分离.如果你可以任意调用函数,那么你会突然增加耦合,这是一个坏的事情.

This is a good thing, as it decouples your presentation from your logic and data. If you can arbitrarily call functions, then you suddenly increase that coupling, which is a bad thing.

另一个原因是 PHP 处理回调的方式.想想你必须如何将该函数传递到你的模板中......大概是这样的:

function blah() {
    return "<p>Oh! Hello, world!</p>";
}

$template = $twig_env->loadTemplate('template.html');
echo $template->render(array('blah'=>'blah'));

在您的模板中,上下文变量 blah 现在只是一个包含 'blah' 的字符串.

In your template, the context variable blah is now just a string containing 'blah'.

在原生 PHP 中,当你使用像这样的变量函数时(尝试像函数一样使用字符串变量),它(或多或少)会执行对该函数的查找,然后调用它.您没有传递函数,只是传递了它的名称.

In vanilla PHP, when you use variable functions like this (try to use a string variable like a function), it (more or less) performs a lookup for that function, then calls it. You are not passing the function, just it's name.

问题是,你不可能将函数传递给模板,因为 PHP 这样做的唯一机制是通过名称字符串,一旦进入模板,该名称就不再是函数名称,而只是一个字符串.

有点啰嗦,但希望对你有帮助!

A little bit long winded, but I hope that helps!

如果您想要更多文档,官方文档是 这里.

If you want more documentation, the official docs are here.