implement channel_view count, the query stuff, css, layout all need some cleanup :(
"""
Template handler
"""
# use Mako
from mako import exceptions
from mako.template import Template
import mako.lookup
# for http.ResponseError
import http
import helpers
# path to template files
TEMPLATE_DIR = "templates"
# path to cached templates
CACHE_DIR = "cache/templates"
# template file extension
TEMPLATE_EXT = "tmpl"
class TemplateError (http.ResponseError) :
"""
Raised by the template module functions
"""
pass
class TemplateLoader (mako.lookup.TemplateLookup) :
"""
Our own specialization of mako's TemplateLookup
"""
def __init__ (self, path, fileext=TEMPLATE_EXT, **env) :
"""
Initialize to load templates located at path, with the given file extension.
The given **env list is supplied to every template render
"""
# store
self.path = path
self.fileext = fileext
self.env = env
# build the TemplateLookup
super(TemplateLoader, self).__init__(directories=[path], module_directory=CACHE_DIR)
@staticmethod
def _render (tpl, env, params) :
"""
Render the given template with given env/params, returning the output as a unicode string, or raising a TemplateError
"""
# build the context from our superglobals, env, and params
ctx = dict(
h = helpers,
)
ctx.update(env)
ctx.update(params)
try :
return tpl.render_unicode(**ctx)
# a template may render other templates
except TemplateError :
raise
except :
details = exceptions.text_error_template().render()
raise TemplateError("Template render failed", status='500 Internal Server Error', details=details)
def lookup (self, name) :
"""
Looks up a template based on the bare "name", which does not include the path or file extension
"""
try :
return self.get_template("%s.%s" % (name, self.fileext))
except :
raise TemplateError("Template broken: %r" % (name, ), status='500 Internal Server Error', details=exceptions.text_error_template().render())
def render (self, name, **params) :
"""
Render a template, using lookup() on the given name
"""
return self._render(self.lookup(name), self.env, params)
def render_to_response (self, name, **params) :
"""
Render a template, returning a http.Response object
"""
return http.Response(self.render(name, **params))
@classmethod
def load (cls, path) :
"""
Loads a template from a specific file
"""
try :
return Template(filename=path, module_directory=CACHE_DIR)
except :
raise TemplateError("Template broken: %r" % (path, ), status='500 Internal Server Error', details=exceptions.text_error_template().render())
@classmethod
def render_file (cls, path, **params) :
"""
Render a template, using load() on the given path. No global environment vars are defined for the render.
"""
return cls._render(cls.load(path), dict(), params)
@classmethod
def render_template (cls, template, **params) :
"""
Render the given template object. No global environment vars are defined for the render.
"""
return cls._render(template, dict(), params)