树枝 - 将功能传递到模板中
-
02-10-2019 - |
题
当前,我将功能放在课堂中,然后将此类的实例传递到模板中,并将所需功能称为类方法。
{{ unneededclass.blah() }}
我需要在下面喜欢
{{ blah() }}
是否可以?
解决方案
更新2015年5月14日
评论者指出,我主要错了。如果您确实需要功能,而不是过滤器或宏,则可以做到 在树枝文档中建议:
$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而言。这意味着他们在环境方面是孤立的,只能代表 语境 您通过您传递的数据阵列传递它们 $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的唯一机制是通过名称弦乐,一旦在模板中,该名称不再是函数名称,而只是字符串。
有点长了一点,但我希望这会有所帮助!
如果您想要更多文档,官方文档是 这里.
其他提示
我的朋友,我像你一样迷路了,但是在搜索网络以寻找答案并没有找到答案之后,我决定看看我自己是否可以做。因此,我想在此处发布解决方案(即使我知道这篇文章是旧的),因为如果您搜索此问题,这是Google上的第一次打击。
它去了,实际上很简单:
我做了一个包含我的功能和变量的课程,例如:
class functionContainer{
function getRandomNumber()
{
return rand();
}
}
$values = array(
'functions'=> new functionContainer()
);
因此,现在我们将$值作为一个数组,其中包含具有“ getRandomNumber()”函数的对象。
渲染模板文件时,将此类作为值包括:
$twig->render('random.html', $values);
这样,在模板文件中,您可以调用此方法来调用该功能并获得结果:
{{ functions.getRandomNumber }}
尽管您不能直接呼叫,但树枝是可扩展的。您可以添加一个可可过滤器,因此您可以应用于传递给模板的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)
而且,您总是可以在过滤器中做更多的事情,例如接受数组作为参数等等。
完整答案:http://twig.sensiolabs.org/doc/advanced.html#id2
我更喜欢这样使用树枝扩展:
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';
}
}
在模板中:
{{ sidebar_menu('some text') }}
使用 匿名课
在管理器/控制器/服务中创建匿名类。
$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' => ...]);
}
};
将参数粘贴到视图
$params=[
'functions' => $functions
];
return new Response($this->twig->render('...:index.html.twig', $params));
在视图中使用功能
{% set rowUrl = functions.rowUrl(entity) %}