Это задокументированное поведение фильтра raw .Я цитирую примечание с этой страницы:
Будьте осторожны при использовании необработанного фильтра внутри выражений:
{% autoescape %}
{% set hello = '<strong>Hello</strong>' %}
{% set hola = '<strong>Hola</strong>' %}
{{ false ? '<strong>Hola</strong>' : hello|raw }}
does not render the same as
{{ false ? hola : hello|raw }}
but renders the same as
{{ (false ? hola : hello)|raw }} {% endautoescape %}
Первый троичный оператор не экранирован: привет отмечен как безопасныйи Twig не экранирует статические значения (см. escape ).Во втором троичном выражении, даже если hello помечен как безопасный, hola остается небезопасным, как и все выражение.Третье троичное выражение помечено как безопасное, и результат не может быть экранирован.
И комментарий к проблеме GitHub разъясняет, что оператор конкатенации помечает вашу строку как небезопасную.Так что в вашем случае
{% set my_html = '<' %}
{# ('1'~my_html) is not safe, so the whole expression is not #}
{{ false
? ('1'~my_html)
: ('2'~my_html)|raw
}}
включает в себя две строки: безопасную, ('2'~my_html)|raw
) и небезопасную, ('1'~my_html)
(поскольку не применяется фильтр raw
), так что примечаниеиз raw
документации говорится, что все выражение остается небезопасным и применяется автоэкранирование.Но в другом случае, когда обе строки помечены как безопасные, все выражение становится безопасным и автоматическое удаление не применяется:
{% set my_html = '<' %}
{# now both strings are safe, so is the whole expression #}
{{ false
? ('1'~my_html)|raw
: ('2'~my_html)|raw
}}