【问题标题】:Pyramid - mako: Escape HTML partiallyPyramid - mako:部分转义 HTML
【发布时间】:2012-06-22 14:45:55
【问题描述】:
我正在使用 Mako 模板创建网页。
有一个部分我使用 | 防止 html 转义。 n.但是,在内部,我还需要显示一些用户生成的条目,我需要在应用程序的视图端转义 HTML。
Pyramid 的方法是什么?
我知道有 CGI 转义,但它似乎不如 Mako 自己的那么好,我想使用它。
目前我有:
from pyramid.compat import escape
escape(str)
谢谢!
【问题讨论】:
标签:
python
python-2.7
pyramid
【解决方案1】:
根据pyramid docs,pyramid.compat.escape 提供cgi.escape(Python 3 上的html.escape)。
根据mako docs,转义功能由markupsafe.escape(x)提供。要记住的一件事可能会有所帮助,MarkupSafe 将在它正在转义的对象上查找__html__ 方法,如果找到它,它将调用该方法并将结果用作转义字符串。这可能会让您在如何转义某些项目方面具有一定的灵活性。
您可以使用其中一种,或者另一种选择(如果可能)来更改您的模板,以便转义确实发生在模板中而不是视图中。
【解决方案2】:
我想我会在这里投入 2 美分,因为我正在寻求解决类似的问题。
就我而言,我对 Python 和 Pyramid 非常陌生,我正在修改 Single File Tasks Tutorial 以创建一个(非常)简单的博客。
我的帖子内容以字符串形式保存在 sqlite 数据库中。问题在于,当内容字符串输出到模板时,html 标签显示为纯文本。
所以而不是:
我得到了:
添加| n 过滤器解决了我的问题。 HTML 内容现在可以在我的帖子正文中正确显示。
我的帖子列表模板 (.mako):
# -*- coding: utf-8 -*-
<%inherit file="layout.mako"/>
<ul id="posts">
% if posts:
% for post in reversed(posts):
<li>
<span class="name">${post['name']}</span>
<span class="content">${post['content'] | n}</span>
</li>
% endfor
% else:
<li>Sorry, no posts...</li>
% endif
</ul>
和 view_config:
@view_config(route_name='list', renderer='list.mako')
def list_view(request):
rs = request.db.execute("select id, name, content from posts")
posts = [dict(id=row[0], name=row[1], content=row[2]) for row in rs.fetchall()]
return {'posts': posts}
This answer helped me out.
我希望这对某人有所帮助。
【解决方案3】:
webhelpers 包提供了一个可能有帮助的转义函数。
来自docs:
webhelpers.html.builder
HTML Builder 提供:
一个以 Python 方式创建 (X)HTML 标记的 HTML 对象。
用于标记包含有意 HTML 标记的字符串的文字类。
一个智能的 escape() 函数,可以保留文字,但会转义其他可能意外包含标记字符(“”、“&”、“”'、“'”)或恶意 Javascript 标记的字符串。转义的字符串作为文字返回,以防止它们在以后被双重转义。
【解决方案4】:
我使用 markdown(以及 Javascript 中的 pagedown)作为一些有限的标记以及一些 HTML 以允许用户自定义他们的输入。
在保存或显示自定义用户标记之前,我清理了 HTML:
from html5lib import sanitizer
from html5lib import html5parser, serializer, treebuilders, treewalkers
# This sanitizer translates all the troublesome tokens
def sanitize2(text):
if (text is None) or isinstance( text, ( int, long ) ):
return text
sanobj = sanitizer.HTMLSanitizer
sanobj.strip_tokens = True
sanobj.lowercaseElementName = True
sanobj.lowercaseAttrName = True
hparser = html5parser.HTMLParser(tree = treebuilders.getTreeBuilder('dom'), tokenizer=sanobj)
dommodel = hparser.parse(text)
serobj = serializer.htmlserializer.HTMLSerializer(sanitize = False)
outstr = ''.join(serobj.serialize(treewalkers.getTreeWalker('dom')(dommodel)))
return outstr
然后,我有一个自定义金字塔过滤器来实际显示它:
import markdown
def jmarkdown(text):
return markdown.markdown(text)
这使得“| jmarkdown”工作!