Search code examples
symfonytwigtwig-filter

Is there a way to check if a Twig filter exists before calling it?


Is there a way to check if a Twig filter exists before calling it?

It seems it doesn't matter what conditions I define before a filter is used, I always get the same error:

'Unknown "myFilter" filter.'

{% if not true %}
  {{ 'Hello World'|myFilter }}
{% endif %}

Solution

  • You always get a Twig_Error_Syntax exception when you try to use an undefined filter, even if you do it in an unreachable place like in your question. This is true for functions as well, see Check if a custom Twig function exists and then call it.

    You can create a custom function to check if a filter exists. But you still can't write code like this:

    {% if filter_exists('myFilter') %}
      {{ 'Hello World'|myFilter }}
    {% endif %}
    

    Instead, you need to create another function as well, so that you have something like this:

    {% if filter_exists('myFilter') %}
      {{ call_filter('Hello World', 'myFilter') }}
    {% endif %}
    

    This way you won't get the exception if the filter doesn't exist.

    Creating those methods is fairly simple:

    $twig->addFunction(new Twig_Function('filter_exists', function(Twig_Environment $env, $filter) {
        return $env->getFilter($filter) !== false;
    }, ['needs_environment' => true]));
    
    $twig->addFunction(new Twig_Function('call_filter', function(Twig_Environment $env, $input, $filter, ...$args) {
        return $env->getFilter($filter)->getCallable()($input, ...$args);
    }, ['needs_environment' => true]));
    

    Or depending on your needs, you could also combine the two, so that the input is returned as-is if the filter doesn't exist:

    $twig->addFunction(new Twig_Function('call_filter_if_it_exists', function(Twig_Environment $env, $input, $filter, ...$args) {
        $filter = $env->getFilter($filter);
    
        if ($filter === false) {
            return $input;
        }
    
        return $filter->getCallable()($input, ...$args);
    }, ['needs_environment' => true]));
    

    Then in Twig:

    {{ call_filter_if_it_exists('Hello World', 'myFilter', 'first arg', 'second arg') }}