diff --git a/reference/dic_tags.rst b/reference/dic_tags.rst index e88002113ea..28b98646f70 100644 --- a/reference/dic_tags.rst +++ b/reference/dic_tags.rst @@ -1247,6 +1247,57 @@ the service is auto-registered and auto-tagged. But, you can also register it ma ], ]); +.. _dic_tags-twig-safe-class: + +twig.safe_class +--------------- + +**Purpose**: Mark a class as safe for Twig's escaper + +.. versionadded:: 8.1 + + The ``twig.safe_class`` resource tag was introduced in Symfony 8.1. + +When Twig prints a value, objects with a ``__toString()`` method are +converted to strings and escaped. Tagging a class with ``twig.safe_class`` +tells Twig's `escaper extension`_ to treat those values as already safe for +the configured escaping strategies and skip re-escaping. This is useful for +value objects that wrap pre-escaped or otherwise trusted output (e.g. an +``HtmlString`` wrapper) without calling the ``raw`` filter at every call +site. + +Unlike most service tags, ``twig.safe_class`` is a +:ref:`resource tag `: it is attached to the class +definition, not to a service. + +.. configuration-block:: + + .. code-block:: yaml + + # config/services.yaml + services: + App\Twig\HtmlString: + resource_tags: + - { name: twig.safe_class, strategy: html } + + .. code-block:: php + + // config/services.php + namespace Symfony\Component\DependencyInjection\Loader\Configurator; + + use App\Twig\HtmlString; + + return function (ContainerConfigurator $container): void { + $container->services() + ->set(HtmlString::class) + ->resourceTag('twig.safe_class', ['strategy' => 'html']); + }; + +The ``strategy`` attribute is required and accepts a string (single strategy) +or a list of strings (multiple strategies). Supported values are ``html``, +``js``, ``css``, ``url``, ``html_attr`` and ``html_attr_relaxed``. The same +class can be tagged several times to mark it safe for several strategies. + validator.constraint_validator ------------------------------ @@ -1277,4 +1328,5 @@ Bridge. .. _`FilesystemLoader`: https://github.com/twigphp/Twig/blob/3.x/src/Loader/FilesystemLoader.php .. _`Twig's documentation`: https://twig.symfony.com/doc/3.x/advanced.html#creating-an-extension .. _`Twig Loader`: https://twig.symfony.com/doc/3.x/api.html#loaders +.. _`escaper extension`: https://twig.symfony.com/doc/3.x/api.html#escaper-extension .. _`PHP class preloading`: https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.preload diff --git a/service_container/tags.rst b/service_container/tags.rst index 45c646b4891..05cc79d83ab 100644 --- a/service_container/tags.rst +++ b/service_container/tags.rst @@ -247,6 +247,8 @@ call to support ``ReflectionMethod``:: :method:`Symfony\\Component\\DependencyInjection\\ContainerBuilder::registerAttributeForAutoconfiguration` callable. +.. _service-tags-resource-tags: + Tagging Non-Service Classes ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/templates.rst b/templates.rst index 01f4b110a5b..63d5aa2cf04 100644 --- a/templates.rst +++ b/templates.rst @@ -1267,6 +1267,13 @@ use the `Twig raw filter`_ to disable the output escaping for that variable: Read the `Twig output escaping docs`_ to learn more about how to disable output escaping for a block or even an entire template. +.. tip:: + + Value objects that hold pre-escaped or trusted content (typically shipped + by bundles, but applications can do the same) can be marked as safe so + Twig won't re-escape them, using the + :ref:`twig.safe_class ` resource tag. + .. _templates-namespaces: Template Namespaces