检查是否存在自定义 Twig 函数,然后调用它 [英] Check if a custom Twig function exists and then call it
问题描述
我测试是否存在自定义 Twig 函数:
I test if a custom Twig function exists:
{% if methodExist('sg_datatables_render') %}
{{ sg_datatables_render(datatable) }}
{% else %}
{{ datatable_render((datatable)) }}
{% endif %}
methodExist
是一个简单的Twig_Function
:
/**
* @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_datatables_render(datatable) }}
似乎总是导致 Twig_Error_Syntax
sg_datatables_render
未注册为 Twig 函数时的异常.
I tried to replicate this, and indeed, {{ sg_datatables_render(datatable) }}
seems to always cause a Twig_Error_Syntax
exception when sg_datatables_render
has not been registered as a Twig function.
然后我尝试了类似的方法.这很难看,但我想知道它是否有效.这个想法是创建一个不存在的函数来避免抛出异常:
I then tried something like this. It's ugly, but I wanted to know if it works. The idea is that a non-existing function will be created to avoid the exception being thrown:
$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]));
但它没有用.我还尝试在新函数中添加一个简单的回调函数,但没有成功.
But it didn't work. I also tried to add a simple callback function to the new function with no success.
我用过滤器尝试了同样的技巧,即:
I tried the same trick with filters, i.e.:
{% if filterExists('sg_datatables_render') %}
{{ datatable|sg_datatables_render }}
{% else %}
{{ datatable|datatable_render }}
{% endif %}
它也没有用.
这样的事情确实有效(耶!):
Something like this does work (yay!):
$twig->addFunction(new Twig_Function('renderDatatable', function(Twig_Environment $twig, $datatable) {
$sgFunction = $twig->getFunction('sg_datatables_render');
if ($sgFunction !== false) {
return $sgFunction->getCallable()($datatable);
}
return $twig->getFunction('datatable_render')->getCallable()($datatable);
}, ['needs_environment' => true]));
然后在 Twig 中:
And then in Twig:
{{ renderDatatable(datatable) }}
renderDatatable
函数专门用于渲染数据表,即它不像您的 methodExist
那样是通用/多用途函数,但它可以工作.您当然可以尝试自己创建一个更通用的实现.
The renderDatatable
function is specific to rendering datatables, i.e. it's not a general/multipurpose function like your methodExist
is, but it works. You can of course try to create a more general implementation yourself.
这是一种更通用的方法.为 methodExist
创建一个额外的 Twig 函数:
Here's a more general approach. Create an additional Twig function to accompany 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]));
然后您可以将原始代码修改为:
Then you could modify your original code to this:
{% 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) }}
<小时>
PS
以下是我如何编写 methodExist
函数:
$twig->addFunction(new Twig_Function('methodExists', function(Twig_Environment $twig, $name) {
return $twig->getFunction($name) !== false;
}, ['needs_environment' => true]));
- 我将
s
添加到函数名称的末尾,因为该函数会检查方法/函数是否存在s. - 我添加了
['needs_environment' =>true]
所以我可以使用$twig
而不是$this->container->get('twig')
.(感谢 yceruto 提供的这个技巧.) 如果函数不存在, getFunction
返回false
(查看文档),所以我将函数体简化为单行返回语句.
- I added
s
to the end of the function's name because the function checks whether a method/function exists. - I added
['needs_environment' => true]
so I can use$twig
instead of$this->container->get('twig')
. (Kudos to yceruto for this tip.) getFunction
returnsfalse
if the function doesn't exist (see the docs), so I simplified the function body to a single-line return statement.
这篇关于检查是否存在自定义 Twig 函数,然后调用它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!