Mako模板过滤器订购

时间:2013-01-08 13:04:15

标签: mako

在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,
&lt;br/&gt;
&lt;br/&gt;My name is
&lt;br/&gt;
&lt;br/&gt;James

我能够找到允许<br>标记无法转义的唯一方法是完全删除'h'过滤器,如下所示:

${user.text | n,nl2br}

但这违背了消毒user.text字段的目标。

如何启动“h”过滤器,然后添加<br>标签?

我错过了缓冲区吗?

2 个答案:

答案 0 :(得分:3)

您看到的行为是由于Markup.replace假定替换字符串不安全这一事实:

>>> from markupsafe import Markup, escape
>>> e = escape(">x\ny")
>>> e
Markup(u'&gt;x\ny')
>>> e.replace("\n", "<br />")
Markup(u'&gt;x&lt;br /&gt;y')

解决方案是告诉markupsafe <br />是否受信任:

>>> e.replace("\n", Markup("<br />"))
Markup(u'&gt;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 }

希望能有所帮助。