如何在mako中正确转义输出(用于XHTML)?
尽管提供了一种很好的方式来使用过滤器处理输出,但这些过滤器都没有做到正确的效果。我们来看这个字符串:
x=u"&\u0092"
这些过滤器的处理方式如下:
x Turns the & into an entity but not the \u0092 (valid XML but not XHTML)
h Exactly the same
u Escapes both, but obviously uses url escaping
entities Only converts named entities, so again only the & is escaped
decode.latin1 The same
HTML使用的是标准的UNICODE字符集,其中有65个字符代码是未定义的(包括0到31和127到159的字符)
这些字符似乎是被遗漏掉的。有没有什么想法?
补充说明
如果我在离线状态下使用这个文件,它似乎是有效的。这可能是内容类型的问题吗?
2 个回答
1
除了验证问题,能够去掉这些字符(反正它们也不太好显示)是很有用的,而且不需要去处理其他任何东西。为此,我在 `lib/helpers.py` 文件里添加了以下这个函数:
__sgml_invalid = re.compile(r'[\x82-\x8c\x91-\x9c\x9f]', re.UNICODE)
def sgmlsafe(text):
lookup = {
130:"‚", #Single Low-9 Quotation Mark
131: "ƒ", #Latin Small Letter F With Hook
132:"„", #Double Low-9 Quotation Mark
133:"…", #Horizontal Ellipsis
134:"†", #Dagger
135:"‡", #Double Dagger
136: "ˆ", #Modifier Letter Circumflex Accent
137:"‰", #Per Mille Sign
138: "Š", #Latin Capital Letter S With Caron
139:"‹", #Single Left-Pointing Angle Quotation Mark
140: "Œ", #Latin Capital Ligature OE
145:"‘", #Left Single Quotation Mark
146:"’", #Right Single Quotation Mark
147:"“", #Left Double Quotation Mark
148:"”", #Right Double Quotation Mark
149:"•", #Bullet
150:"–", #En Dash
151:"—", #Em Dash
152: "˜", #Small Tilde
153:"™", #Trade Mark Sign
154: "š", #Latin Small Letter S With Caron
155:"›", #Single Right-Pointing Angle Quotation Mark
156: "œ", #Latin Small Ligature OE
159: "Ÿ" #Latin Capital Letter Y With Diaeresis
}
return __sgml_invalid.sub(lambda x: lookup[ord(x.group())], text)
然后你可以通过编辑 environment.py
来把这个函数作为一个过滤器提供出来:
config['pylons.app_globals'].mako_lookup = TemplateLookup(
...
imports=[....,'from appname.lib.helpers import sgmlsafe',...]
这样一来,它就可以在你的模板中使用了:
${c.content|n,sgmlsafe}
2
在HTML中,除非你特意使用ASCII字符集,否则不需要把Unicode字符转换成&#xxxx;
这种形式。其实,使用命名实体来转义字符更简单、更高效,然后把整个字符串编码成UTF-8格式,直接这样写就可以了。你最好在HTTP头部或者在<meta>
标签中声明你使用的编码方式。
编辑:
如果我在离线状态下使用这个文件,它似乎可以通过验证。这可能是内容类型的问题吗?
没错。你可以通过HTTP头部来强制使用UTF-8字符集,或者直接在HTML中通过meta标签来指定:
<meta http-equiv="Content-Type" content="application/xhtml+xml;charset=utf-8" />