Skip to content

Instantly share code, notes, and snippets.

@oubiwann
Created October 7, 2012 03:24
Rendering ReST with Twisted Templates
import const, fragments, renderer
class ContentPage(BasePage):
"""
Note that the BasePage class is not included in this
example. It and its parent class manage template
loading, slot-filling, etc.
"""
contentType = const.contentTypes["rst"]
contentData = ""
# Hobo caching
_cachedContent = ""
def renderContentData(self):
if not self._cachedContent:
if self.contentType == const.contentTypes["rst"]:
self._cachedContent = renderer.ReSTContent(
self.contentData)
elif self.contentType == const.contentTypes["html"]:
self._cachedContent = self.contentData
return self._cachedContent
@renderer
def topnav(self, request, tag):
return fragments.TopNavFragment()
@renderer
def contentarea(self, request, tag):
return fragments.ContentFragment(self.renderContentData())
from twisted.web.iweb import IRenderable
from zope.interface import implements
class ReSTContent(object):
"""
Though not strictly necessary as a dedicated class, I wanted to
put this code here to assist with organization of content type
renderers, as this will not be the only one.
"""
implements(IRenderable)
def __init__(self, rstData):
self.rstData = rstData
def render(self, request):
return utils.rstToStan(self.rstData)
from docutils.core import publish_string as render_rst
from twisted.web.template import Tag, XMLString
def rstToHTML(rst):
overrides = {
'output_encoding': 'unicode',
'input_encoding': 'unicode'
}
return render_rst(
rst.decode("utf-8"), writer_name="html",
settings_overrides=overrides)
def checkTag(tag):
if isinstance(tag, basestring):
return False
return True
def rstToStan(rst):
html = rstToHTML(rst)
# fix a bad encoding in docutils
html = html.replace('encoding="unicode"', '')
stan = XMLString(html).load()[0]
# we're always going to get the same structure back, at least
# for the installed version of docutils, so let's trip out the
# crap that we don't need (also, let's safeguard against future
# changes)
if stan.tagName != "html":
raise ValueError("Unexpected top-level HTML tag.")
# let's ditch the children whose sole contents are "\n" strings
head, body = [x for x in stan.children if checkTag(x)]
if head.tagName != "head":
raise ValueError("Expected 'head' node, got '%s'" % (
head.tagName))
if body.tagName != "body":
raise ValueError("Expected 'body' node, got '%s'" % (
body.tagName))
# by just returning the contents of the body tag, we're avoiding
# all the CSS and, in fact, the complete HTML file that the
# docutils ReST renderer provides by default
return body.children
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment