php twig - 将函数传递给模板
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3595727/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
twig - pass function into template
提问by StoneHeart
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() }}
I need to do like below
我需要做如下
{{ blah() }}
Is it possible?
是否可以?
回答by Austin Hyde
Update 5/14/2015
2015 年 5 月 14 日更新
Commenters point out that I'm mostly wrong. If you really need a function, and not a filter or macro, you can do it as suggested in the Twig docs:
评论者指出我大多是错的。如果您确实需要一个函数,而不是过滤器或宏,则可以按照 Twig 文档中的建议进行操作:
$twig = new Twig_Environment($loader);
$function = new Twig_SimpleFunction('blah', function () {
// ...
});
$twig->addFunction($function);
And use like
并使用像
{{ blah() }}
In short, no, this is not possible.
简而言之,不,这是不可能的。
However, hope is not lost!
然而,希望并没有消失!
Filters
过滤器
If this function blah()
of yours is meant to modify an existing variable, then it is a filter.
如果blah()
你的这个函数是为了修改一个现有的变量,那么它就是一个filter。
An example:
一个例子:
//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)
(第一个参数是您要过滤的变量,第二个参数是通过正常方式提供的)
Macros
宏
If, as you have indicated above, your function simply outputs HTML, then it is a good candidate for a macro.
如果,正如您在上面指出的,您的函数只是输出 HTML,那么它很适合使用宏。
An example:
一个例子:
{# in your template #}
{% macro say_hello() %}
<p>Oh! Hello, world!</p>
{% endmacro %}
{# ... later on ... #}
{{ _self.say_hello() }}
Or with parameters:
或者带参数:
{% 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') }}
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 contextyou pass them via the data array you pass in the $template->render()
method.
需要记住的是,在 MVC 方面,Twig 模板代表一个视图。这意味着它们就其环境而言是隔离的,并且只能表示您通过在方法中传递的数据数组传递给它们的上下文$template->render()
。
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 badthing.
这是一件好事,因为它使您的演示文稿与您的逻辑和数据分离。如果你可以随意调用函数,那么你会突然增加这种耦合,这是一件坏事。
The other reason for this is the way PHP handles callbacks. Think about how you would have to pass that function into your template... Probably something like this:
另一个原因是 PHP 处理回调的方式。想想你将如何将该函数传递到你的模板中......可能是这样的:
function blah() {
return "<p>Oh! Hello, world!</p>";
}
$template = $twig_env->loadTemplate('template.html');
echo $template->render(array('blah'=>'blah'));
In your template, the context variable blah
is now just a string containing 'blah'
.
在您的模板中,上下文变量blah
现在只是一个包含'blah'
.
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 notpassing the function, just it's name.
在普通 PHP 中,当您使用这样的变量函数时(尝试像函数一样使用字符串变量),它(或多或少)会执行该函数的查找,然后调用它。你没有传递函数,只是它的名字。
The thing is, you cannot possibly pass a function into a template, because PHP's only mechanism for doing this is by name-string, and once inside a template, that name is no longer a function name and just a string.
问题是,您不可能将函数传递到模板中,因为 PHP 执行此操作的唯一机制是通过名称字符串,一旦进入模板,该名称就不再是函数名称而只是字符串。
A little bit long winded, but I hope that helps!
有点啰嗦,但我希望有帮助!
If you want more documentation, the official docs are here.
如果你想要更多的文档,官方文档在这里。
回答by Corrensanders
I was as lost as you were, my friend, but after searching the web for an answer and found none, I decided to see if I could do it myself. Therefore, I wanted to post my solution here (even though I know this post is old), because this is the first hit on google if you search for this problem.
我和你一样迷茫,我的朋友,但在网上搜索答案并没有找到答案后,我决定看看我是否可以自己做。因此,我想在这里发布我的解决方案(即使我知道这篇文章很旧),因为如果您搜索此问题,这是 google 上的第一次点击。
Here it go, it is quite simple actually:
就这样吧,其实很简单:
I made a class which contains my functions and variables, for example:
我创建了一个包含我的函数和变量的类,例如:
class functionContainer{
function getRandomNumber()
{
return rand();
}
}
$values = array(
'functions'=> new functionContainer()
);
So now we have $values as an array, which contains this object with a function "getRandomNumber()".
所以现在我们有 $values 作为一个数组,它包含这个带有函数“getRandomNumber()”的对象。
When rendering the template file, include this class as a value:
渲染模板文件时,将此类包含为值:
$twig->render('random.html', $values);
This way, inside the template file, you can just call this method to call the function and get your result:
这样,在模板文件中,您只需调用此方法即可调用函数并获得结果:
{{ functions.getRandomNumber }}
回答by Plamen Dragiyski
Although you cannot PHP callable directly, twig is extensible. You can add a callable filter, so you can apply to PHP functions passed to template.
尽管您不能直接调用 PHP,但 twig 是可扩展的。您可以添加一个可调用过滤器,以便您可以应用于传递给模板的 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);
}
}
Now if you pass variable my_func
to template, you can do my_func|call(arg1, arg2)
. You can even do higher order functions "array_filter"|call(my_array, my_func)
and you can always do more things in filter like accepting array as parameters and so on.
现在,如果将变量传递my_func
给模板,则可以执行my_func|call(arg1, arg2)
. 你甚至可以做高阶函数"array_filter"|call(my_array, my_func)
,你总是可以在过滤器中做更多的事情,比如接受数组作为参数等等。
回答by merqlove
Full answer: http://twig.sensiolabs.org/doc/advanced.html#id2
完整答案:http: //twig.sensiolabs.org/doc/advanced.html#id2
I prefer to use Twig Extension like this:
我更喜欢像这样使用 Twig Extension:
namespace Some\Twig\Extensions;
class MenuExtensions extends \Twig_Extension
{
public function getFunctions()
{
return array(
new \Twig_SimpleFunction('sidebar_menu', [$this, 'generate_sidebar_menu']),
);
}
public function generate_sidebar_menu($menu){
return $menu;
}
public function getName()
{
return 'menu';
}
}
In template:
在模板中:
{{ sidebar_menu('some text') }}
回答by Ajsti.pl - Maciej Szewczyk
Using Anonymous class
使用匿名类
Create anonymous class in manager/controller/service ..
在 manager/controller/service 中创建匿名类..
$functions = new class($router)
{
public function __construct($router)
{
$this->router = $router;
}
public function getRowUrl(FileManager $fileManager)
{
if ($fileManager->isNode()) {
return $this->router->generate('...', ['parent' => ...]);
}
return $this->router->generate('...', ['entity' => ...]);
}
};
Paste parameter into view
将参数粘贴到视图中
$params=[
'functions' => $functions
];
return new Response($this->twig->render('...:index.html.twig', $params));
Use function in view
在视图中使用函数
{% set rowUrl = functions.rowUrl(entity) %}