--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/template.py Sun Feb 08 03:17:07 2009 +0200
@@ -0,0 +1,124 @@
+"""
+ Template handler
+"""
+
+from mako import exceptions
+from mako.template import Template
+import mako.lookup
+
+from qmsk.web import http, 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)