1

这是一个Twig Fiddle。在那里你会注意到这个包含文件:

{# include.twig #}

{{ text }}

而这个主文件,在将文本变量传递给包含文件之前多次尝试将其标记为安全:

{# main.twig #}

1. Pass string with HTML

{{ include('include.twig', { text: '<p>Text</p>' }) }}


2. Pass string with HTML marked safe with raw filter

{{ include('include.twig', { text: '<p>Text</p>'|raw }) }}


3. Pass variable set with string literal marked safe with raw filter

{% set text = '<p>Text</p>'|raw %}

{{ include('include.twig', { text: text }) }}


4. Pass variable set with captured chunk of text

{% set text %}<p>Text</p>{% endset %} 

{{ include('include.twig', { text: text }) }}

以下是渲染此模板的结果:

1. Pass string with HTML

&lt;p&gt;Text&lt;/p&gt;

2. Pass string with HTML marked safe with raw filter

&lt;p&gt;Text&lt;/p&gt;

3. Pass variable set with string literal marked safe with raw filter

&lt;p&gt;Text&lt;/p&gt;

4. Pass variable set with captured chunk of text

<p>Text</p>

第一次尝试建立了不需要的 HTML 转义行为。策略 2 和 3 尝试使用|raw过滤器来避免转义,但都失败了。策略 4,使用set标签来捕获一大块文本,效果很好。

过滤器文档|raw说:

raw 过滤器将该值标记为“安全”,这意味着在启用了自动转义的环境中,如果 raw 是应用于它的最后一个过滤器,则不会转义此变量:

标签文档set说:

如果启用自动输出转义,Twig 只会在捕获文本块时认为内容是安全的。

除非我遗漏了一些东西,否则这些似乎是“安全”的两种不同定义,set标签下提到的一个意思是super-extra-safe

有没有办法将包含超安全HTML 的字符串文字传递到模板中,而不会用难看的块捕获set块污染我的文件?

4

1 回答 1

0

答案是否定的,你不能,因为twig不会转义静态表达式。raw编译模板时甚至会忽略过滤器。

{% set hello = "<strong>Hello</strong>" %}
{% set hello = "<strong>Hello</strong>"|raw %}

上面两行将在相同的源代码中编译

// line 1        
$context["hello"] = "<strong>Hello</strong>";
// line 2
$context["hello"] = "<strong>Hello</strong>";

资源


编辑:

如果您真的想这样做,您可以编写自己的包含/设置节点或添加一个过滤器,该过滤器返回一个Twig\Markup

<?php
    $twig->addFilter(new \Twig\TwigFilter('safe', function($v) {
         return new \Twig\Markup($v);
    });
{% include 'text.html' with { 'text': 'Hello <strong>World</strong>'|safe, } %}

你好世界

于 2020-02-06T07:06:51.657 回答