Files
Twig/doc/filters/escape.rst
T
2026-05-21 14:45:29 +02:00

152 lines
4.8 KiB
ReStructuredText

``escape``
==========
The ``escape`` filter escapes a string using strategies that depend on the
context.
By default, it uses the HTML escaping strategy:
.. code-block:: html+twig
<p>
{{ user.username|escape }}
</p>
For convenience, the ``e`` filter is defined as an alias:
.. code-block:: html+twig
<p>
{{ user.username|e }}
</p>
The ``escape`` filter can also be used in other contexts than HTML thanks to
an optional argument which defines the escaping strategy to use:
.. code-block:: twig
{{ user.username|e }}
{# is equivalent to #}
{{ user.username|e('html') }}
And here is how to escape variables included in JavaScript code:
.. code-block:: twig
{{ user.username|escape('js') }}
{{ user.username|e('js') }}
The ``escape`` filter supports the following escaping strategies for HTML
documents:
* ``html``: escapes a string for the **HTML body** context,
or for HTML attributes values **inside quotes**.
* ``js``: escapes a string for the **JavaScript** context. This is intended for
use in JavaScript or JSON strings, and encodes values using backslash escape
sequences.
* ``css``: escapes a string for the **CSS** context. CSS escaping can be
applied to any string being inserted into CSS and escapes everything except
alphanumerics.
* ``url``: escapes a string for the **URI or parameter** contexts. This should
not be used to escape an entire URI; only a subcomponent being inserted.
* ``html_attr``: escapes a string when used as an **HTML attribute** name, and
also when used as the value of an HTML attribute **without quotes**
(e.g. ``data-attribute={{ some_value }}``).
* ``html_attr_relaxed``: like ``html_attr``, but **does not** escape the ``@``, ``:``,
``[`` and ``]`` characters. You may want to use this in combination with front-end
frameworks that use attribute names like ``v-bind:href`` or ``@click``. But, be
aware that in some processing contexts like XML, characters like the colon ``:``
may have meaning like for XML namespace separation.
Note that doing contextual escaping in HTML documents is hard and choosing the
right escaping strategy depends on a lot of factors. Please, read related
documentation like `the OWASP prevention cheat sheet
<https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.md>`_
to learn more about this topic.
.. note::
Internally, ``escape`` uses the PHP native `htmlspecialchars`_ function
for the HTML escaping strategy.
.. caution::
When using automatic escaping, Twig tries to not double-escape a variable
when the automatic escaping strategy is the same as the one applied by the
escape filter; but that does not work when using a variable as the
escaping strategy:
.. code-block:: twig
{% set strategy = 'html' %}
{% autoescape 'html' %}
{{ var|escape('html') }} {# won't be double-escaped #}
{{ var|escape(strategy) }} {# will be double-escaped #}
{% endautoescape %}
When using a variable as the escaping strategy, you should disable
automatic escaping:
.. code-block:: twig
{% set strategy = 'html' %}
{% autoescape 'html' %}
{{ var|escape(strategy)|raw }} {# won't be double-escaped #}
{% endautoescape %}
.. tip::
The ``html_attr`` escaping strategy can be useful when you need to escape a
**dynamic HTML attribute name**:
.. code-block:: html+twig
<p {{ your_html_attr|e('html_attr') }}="attribute value">
It can also be used for escaping a **dynamic HTML attribute value** if it is
not quoted, but this is **less performant**. Instead, it is recommended to
quote the HTML attribute value and use the ``html`` escaping strategy:
.. code-block:: html+twig
<p data-content="{{ content|e('html') }}">
{# this is equivalent, but less performant #}
<p data-content={{ content|e('html_attr') }}>
Custom Escapers
---------------
You can define custom escapers by calling the ``setEscaper()`` method on the
escaper runtime instance. It accepts two arguments: the strategy name and a PHP
callable that accepts a string to escape and the charset::
use Twig\Runtime\EscaperRuntime;
$twig = new \Twig\Environment($loader);
$escaper = fn ($string, $charset) => $string;
$twig->getRuntime(EscaperRuntime::class)->setEscaper('identity', $escaper);
# Usage in a template:
# {{ 'Twig'|escape('identity') }}
.. note::
Built-in escapers cannot be overridden mainly because they should be
considered as the final implementation and also for better performance.
Arguments
---------
* ``strategy``: The escaping strategy
* ``charset``: The string charset
.. _`htmlspecialchars`: https://www.php.net/htmlspecialchars