Symfony 检查自定义细枝函数是否存在,然后调用它
我测试是否存在自定义细枝函数:Symfony 检查自定义细枝函数是否存在,然后调用它,symfony,twig,Symfony,Twig,我测试是否存在自定义细枝函数: {% if methodExist('sg_datatables_render') %} {{ sg_datatables_render(datatable) }} {% else %} {{ datatable_render((datatable)) }} {% endif %} methodExist是一个简单的Twig\u函数: /** * @param $name * @return bool */ public functio
{% if methodExist('sg_datatables_render') %}
{{ sg_datatables_render(datatable) }}
{% else %}
{{ datatable_render((datatable)) }}
{% endif %}
methodExist
是一个简单的Twig\u函数
:
/**
* @param $name
* @return bool
*/
public function methodExist($name){
if($this->container->get('twig')->getFunction($name)){
return true;
}else{
return false;
}
}
但我有一个例外:
Unknown "sg_datatables_render" function. Did you mean "datatable_render"?
500 Internal Server Error - Twig_Error_Syntax
我试图复制这一点,事实上,
{{sg\u datatables\u render(datatable)}}
似乎总是在sg\u datatables\u render
未注册为细枝函数时导致Twig\u Error\u语法
异常
然后我尝试了类似的东西。它很难看,但我想知道它是否有效。其思想是创建一个不存在的函数,以避免引发异常:
$twig->addFunction(new Twig_Function('methodExist', function(Twig_Environment $twig, $name) {
$hasFunction = $twig->getFunction($name) !== false;
if (!$hasFunction) {
// The callback function defaults to null so I have omitted it here
return $twig->addFunction(new Twig_Function($name));
}
return $hasFunction;
}, ['needs_environment' => true]));
但它不起作用。我还尝试向新函数添加一个简单的回调函数,但没有成功
我用过滤器尝试了同样的技巧,即:
{% if filterExists('sg_datatables_render') %}
{{ datatable|sg_datatables_render }}
{% else %}
{{ datatable|datatable_render }}
{% endif %}
它也不起作用
解决方案1:
{{renderDatatable(datatable)}}
像这样的东西确实管用(耶!):
然后在细枝上:
{{ renderDatatable(datatable) }}
renderDatatable
函数专门用于呈现数据表,也就是说,它不像您的methodExist
那样是一个通用/多用途函数,但它可以工作。当然,您可以尝试自己创建一个更通用的实现
解决方案2:
{{fn('sg_datatables_render',datatable)}
这里有一个更一般的方法。创建附加的细枝函数以伴随methodExist
:
$twig->addFunction(new Twig_Function('fn', function(Twig_Environment $twig, $name, ...$args) {
$fn = $twig->getFunction($name);
if ($fn === false) {
return null;
}
// You could add some kind of error handling here
return $fn->getCallable()(...$args);
}, ['needs_environment' => true]));
然后您可以将原始代码修改为:
{% if methodExist('sg_datatables_render') %}
{{ fn('sg_datatables_render', datatable) }}
{% else %}
{{ datatable_render((datatable)) }}
{% endif %}
甚至可以使用三元运算符:
{{ methodExist('sg_datatables_render') ? fn('sg_datatables_render', datatable) : datatable_render(datatable) }}
附言 下面是我如何编写
methodExist
函数:
$twig->addFunction(new Twig_Function('methodExists', function(Twig_Environment $twig, $name) {
return $twig->getFunction($name) !== false;
}, ['needs_environment' => true]));
s
,因为该函数检查方法/函数是否存在s['needs\u environment'=>true]
,这样我就可以使用$twig
而不是$this->container->get('twig')
。(这一点值得向yceruto致敬。)getFunction
如果函数不存在,则返回false
,因此我将函数体简化为单行返回语句您是否完全确定在这种情况下不会在别处调用
sg\u datatables\u render
?顺便说一句,通过将'needs\u environment'=>true
选项传递到methodExist
定义,您可以使用environment$twig
作为此函数的第一个参数,因此,容器
调用将消失。。。尝试dump(methodExist('sg\u datatables\u render'))
了解发生了什么。
$twig->addFunction(new Twig_Function('methodExists', function(Twig_Environment $twig, $name) {
return $twig->getFunction($name) !== false;
}, ['needs_environment' => true]));