Reputation: 14641
I am using Mako templates to create a web page.
There is a section in which I prevent html escaping using | n. However, inside, I also need to show some user generated entries for which I need to escape the HTML on the view side of the apps.
What is the way to go with Pyramid for this?
I know there is CGI escaping but it does not seem as good as Mako's own and I would like to use that.
currently I have:
from pyramid.compat import escape
escape(str)
Thank you!
Upvotes: 2
Views: 2469
Reputation: 65
I use markdown (and pagedown in Javascript) for some limited markup as well as some HTML to allow users to customize their inputs.
Before saving or displaying the custom user markup, I clean up the HTML with:
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
Then, I have a custom pyramid filter to actually display it:
import markdown
def jmarkdown(text):
return markdown.markdown(text)
This makes "| jmarkdown" work!
Upvotes: 0
Reputation: 2956
I thought I would throw my 2 cents in here since I was looking to solve a similar issue. In my case I'm very new to Python and Pyramid and I am modifying the Single File Tasks Tutorial to create a (very) simple blog.
My post content was saved as a string in a sqlite database. The problem was that when the content string was output to the template html tags were appearing as plain text.
So rather than:
I was getting:
Adding the | n
filter solved my issue. HTML content now displays correctly in my post bodies.
My template (.mako) for the list of posts:
# -*- 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>
and the 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}
I hope this helps someone.
Upvotes: 3
Reputation: 1184
The webhelpers package offers a escape function that might help. From the docs:
webhelpers.html.builder
HTML Builder provides:
an HTML object that creates (X)HTML tags in a Pythonic way.
a literal class used to mark strings containing intentional HTML markup.
a smart escape() function that preserves literals but escapes other strings that may accidentally contain markup characters (“<”, “>”, “&”, ‘”’, “’”) or malicious Javascript tags. Escaped strings are returned as literals to prevent them from being double-escaped later.
Upvotes: 2
Reputation: 43071
According to the pyramid docs, pyramid.compat.escape
provides cgi.escape
(html.escape
on Python 3).
According to the mako docs, the escape functionality is provided by markupsafe.escape(x)
. One thing to keep in mind that might be helpful is that MarkupSafe will look for an __html__
method on the object it is escaping, and if it finds it, it will call that method and use the results as the escaped string. This might allow you some flexibility in how certain items are escaped.
You can either use one of these, or another option is (if possible) to change your template so that the escaping actually does happen in the template rather than the view.
Upvotes: 3