在Mako中标记字符串为安全

11 投票
2 回答
5035 浏览
提问于 2025-04-15 16:33

我正在使用Pylons和Mako模板,但我总是要输入这些代码,觉得很麻烦:

${ h.some_function_that_outputs_html() | n }

我想要找到一种方法,把某个函数或变量标记为安全(在Django中可以做到),这样我就不需要每次都加上管道符了。有没有什么好主意?

2 个回答

3

根据Mako文档关于过滤的说明,在创建新的Template时,你可以设置默认的过滤器,这些过滤器会在模板内部应用。同时,对于TemplateLookup来说,这些默认过滤器会适用于它查找的所有模板,使用的参数是default_filters

Pylons在config/environment.py文件中使用这个参数来为你的项目设置默认值:

# Create the Mako TemplateLookup, with the default auto-escaping
config['pylons.app_globals'].mako_lookup = TemplateLookup(
    directories=paths['templates'],
    error_handler=handle_mako_error,
    module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
    input_encoding='utf-8', default_filters=['escape'],
    imports=['from webhelpers.html import escape'])

这就是为什么你会默认得到转义效果(而如果你单独使用Mako就不会这样)。所以你可以选择在配置文件中全局更改这个设置,或者不依赖标准查找。需要注意的是,如果你这样做了,当然要明确使用过滤器来转义那些确实需要转义的内容。

你也可以使用Pylons的助手h.literal传递一个“标记为安全”的字符串。例如,如果你传递h.literal('This will <b>not</b> be escaped')给模板,假设这个变量叫spam,那么你可以直接使用${spam}而不需要转义。

如果你想在模板内部调用某个函数时达到同样的效果,这个函数需要返回这样的字面量,或者为这个函数提供一个助手,如果你想保持原函数不变,可以在结果上调用h.literal。(或者我想你也可以通过“过滤定义”来调用它(参见上面的Mako文档),不过我还没有尝试过这个)

10

我刚发现,如果你在你的类里面放一个html方法,那么Mako就会直接调用这个方法,并把它返回的内容输出到模板里。

所以我这样做了:

def __html__(self):
    return unicode(self)

这基本上就是h.literal的作用。

撰写回答