首先,我很清楚 twig 是服务器端,而 JavaScript 是客户端。
我仍然想使用 twigs
path()
函数来渲染我的 JavaScript 代码并将 JavaScript 变量作为原始字符串注入,但它总是被转义,我很好奇为什么原始过滤器不适用?
我的 twig 文件中有以下 JavaScript(简化版):
// file.html.twig
<script>
print '<a href="{{ path('article_edit', {id: ("' + full['id'] + '"|raw)}) }}">Linktext</a>';
</script>
由于
article_edit
的路径是 /articles/{id}/edit
我希望 twig 执行以下两个步骤:
// Expected twig-render, step 1
<script>
print '<a href="/articles/{id}/edit">Linktext</a>';
</script>
第 2 步:
{id}
然后被替换为我给定的字符串 ' + full['id'] + '
,从而产生有效的 Javascript:
// Expected twig-render, final step
<script>
print '<a href="/articles/' + full['id'] + '/edit">Linktext</a>';
</script>
这将在客户端呈现给
<a href="/articles/1/edit">Linktext</a>
但是,即使我使用了
|raw
过滤器,twig 仍然对字符串进行 urlencode。产生以下输出:
// Actual twig-render
<script>
print '<a href="/articles/%27%20+%20full%5B%27id%27%5D%20+%20%27/edit">Linktext</a>';
</script>
以下树枝代码确实具有完全相同的输出:
{{ path('article_edit', {id: ("' + full['id'] + '")}) }} // no filter
{{ path('article_edit', {id: ("' + full['id'] + '"|raw)}) }} // filter on the id
{{ path('article_edit', {id: ("' + full['id'] + '")})|raw }} // filter on the function
{{ path('article_edit', {id: ("' + full['id'] + '"|raw)})|raw }} // filter on both id and function
如果您仍然认为这是客户端和服务器端渲染的问题,我创建了一个小小的 PHP 小提琴来演示问题和使用普通 PHP 的预期行为,没有树枝:https://ideone.com/amZ4T4
为什么 twig 会忽略过滤器并对 JavaScript 进行 urlencode 编码?这不是过滤器的用途吗,这样我就可以在 twig 中构建动态 JavaScript 代码?
我现在使用硬编码路径作为解决方法,但我很好奇为什么过滤器被忽略......
twig urlencodes 字符串,忽略原始过滤器
完全正确。正如它应该的那样。正如文档中所解释的:
过滤器将值标记为“安全”,这意味着在启用自动转义的环境中,如果 raw 是最后一个应用于该变量的过滤器,则该变量将不会被转义:raw
此过滤器只是防止 HTML 实体转义,以防您想按原样输出它们。
例如如果您的输出包含
<b>bold</bold>
,它将逐字呈现,而不是作为 <b>bold</b>
。
您的输出根本没有被转义,因此
raw
无法阻止字符串的转义。
它正在被 URL 编码,正如您所看到的,因为它是
path()
的输出,它被假定为一个 URL,并且通常是 您想要 编码为 URL 的东西。
这甚至不是由 Twig 控制的。
path
函数由 Twig Symfony 桥中的 RoutingExtension
定义(here),它唯一做的就是使用 UrlGeneratorInterface::generate
获取 URL,并将其返回给模板。
URL 始终会生成 URL 编码...因为它是一个 URL。
乍一看,这似乎使用了错误的工具来完成这项工作。