How to prevent a Custom Twig Function from escaping the output in Symfony 5

Twig allows you to create and register custom functions and filters to implement stuff that may not be included with the default ones in Twig. One of the most common examples of helper functions created in Twig, is the function that automatically prints an IMG tag in the view, like this:

{{ image_tag("https://cdn.domain.com/myimage.jpg") }}

The function, in this case, expects as the first argument the URL of the image that will be used as src of the image tag. The problem itself is, that most of the developers that create such functions, will use as well the raw filter to print the content of the function like this:

{{ image_tag("https://cdn.domain.com/myimage.jpg")|raw }}

Because they didn't implement the custom function properly, so without the raw filter, the printed HTML would be escaped like this:

<img src="https://cdn.domain.com/myimage.jpg" />

As the HTML entities are encoded, there will be no image on the page but plain text. To fix that, you would simply use the raw tag to unescape the HTML and that's it, however, there's a more elegant way to print the raw HTML without using the extra filter on the view.

Disable auto-escaping in custom functions and filters

It's possible to disable the auto-escaping of the returned value of your custom Twig function by specifying the 'is_safe' option in the declaration of the function:

<?php

// src/Twig/AppExtension.php
namespace App\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class AppExtension extends AbstractExtension {
    // ... 

    public function getFunctions() {
        return [
            new TwigFunction('function_name', [$this, 'localFunctionToUse'], [
                'is_safe' => [
                    'html'
                ]
            ]),
        ];
    }

    // ...
}

Full example

The following extension shows a full example of how to implement the mentioned function of image_tag:

<?php

// src/Twig/AppExtension.php
namespace App\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class AppExtension extends AbstractExtension {
    public function getFunctions() {
        return [
            new TwigFunction('image_tag', [$this, 'image_tag'], [
                'is_safe' => [
                    'html'
                ]
            ]),
        ];
    }
    
    public function image_tag($imagesrc): string{
        return "<img src=\"{$imagesrc}\" />";
    }
}

You may apply the same principle if you are using a custom filter.

Happy coding ❤️!

This could interest you

Become a more social person