在mako模板中输出一些UGC($user.text
)时,我想使用mako过滤器'h'清理内容,然后添加一些<br>
标签代替换行符,以便有点格式化。
但是,似乎mako忽略了我应用“h”过滤器的顺序,现在我的<br>
标签正在转义而不会呈现。
这是我的添加过滤器:
<%
def nl2br(str):
return str.replace("\n", "<br/>")
%>
这是我的测试字符串:
hello,
My name is
James
以下带过滤器的mako标签:
${user.text | n,h,nl2br}
${user.text | n,nl2br,h}
...生成相同的html,<br>
代码已转义:
hello,
<br/>
<br/>My name is
<br/>
<br/>James
我能够找到允许<br>
标记无法转义的唯一方法是完全删除'h'过滤器,如下所示:
${user.text | n,nl2br}
但这违背了消毒user.text
字段的目标。
如何启动“h”过滤器,然后添加<br>
标签?
我错过了缓冲区吗?
答案 0 :(得分:3)
您看到的行为是由于Markup.replace
假定替换字符串不安全这一事实:
>>> from markupsafe import Markup, escape >>> e = escape(">x\ny") >>> e Markup(u'>x\ny') >>> e.replace("\n", "<br />") Markup(u'>x<br />y')
解决方案是告诉markupsafe
<br />
是否受信任:
>>> e.replace("\n", Markup("<br />")) Markup(u'>x<br />y')
因此,您的nl2br
过滤器应为:
from markupsafe import Markup
def nl2br(s):
return s.replace("\n", Markup("<br />"))
然后${user.text|h,nl2br}
应按预期工作。
答案 1 :(得分:0)
我无法弄清楚上面的订单是怎么回事,所以如果你有答案,请在这里发布。相反,我使用了一种解决方法......
由于h
标记在过滤顺序中触发太晚,因此我创建了自己的版本并强制它通过调用__str__
返回已清理的HTML。
def early_html_escape(string):
"""Run markupsafe escaping and force the result to string."""
import markupsafe
return markupsafe.escape(string).__str__()
这允许我首先通过HTML转义传递用户的文本,然后传递nl2br
过滤器,而不将<br>
标记转换为HTML实体。
${user.text | early_html_escape,nl2br }
希望能有所帮助。