我试图复制这个,事实上,{{ sg_datatables_render(datatable) }} 似乎总是在 sg_datatables_render 尚未注册为 Twig 函数时导致 Twig_Error_Syntax 异常。
然后我尝试了类似的方法。这很难看,但我想知道它是否有效。这个想法是创建一个不存在的函数来避免抛出异常:
$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) }}
这样的事情确实有效(耶!):
$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 中:
{{ renderDatatable(datatable) }}
renderDatatable 函数专用于呈现数据表,即它不像您的 methodExist 那样是通用/多用途函数,但它可以工作。您当然可以尝试自己创建一个更通用的实现。
解决方案 2:{{ fn('sg_datatables_render', datatable) }}
这是一种更通用的方法。创建一个额外的 Twig 函数来陪伴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) }}
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 如果函数不存在 (see the docs),所以我将函数体简化为单行返回语句。