检查是否存在自定义Twig函数,然后调用它

时间:2018-01-12 14:18:14

标签: symfony twig

我测试是否存在自定义Twig函数:

print (df)
    A    B    C    account
0   0  230  140  Jones LLC
1  20  192  215   Alpha Co

{% 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;
    }
}

1 个答案:

答案 0 :(得分:1)

我试图复制这个,事实上,当{{ sg_datatables_render(datatable) }}尚未注册为Twig函数时,Twig_Error_Syntax似乎总是会导致sg_datatables_render异常。

然后我尝试了这样的事情。这很难看,但我想知道它是否有效。我们的想法是创建一个不存在的函数来避免抛出异常:

$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]));
  1. 我将s添加到函数名称的末尾,因为该函数检查方法/函数是否存在 s
  2. 我添加了['needs_environment' => true],因此我可以使用$twig代替$this->container->get('twig')。 (对于这个提示,请向yceruto致谢。)
  3. 如果函数不存在(see the docs),则
  4. getFunction会返回false,因此我将函数体简化为单行返回语句。