lib/template.py
changeset 46 73aef9705d6c
parent 45 e94ab812c0c8
child 47 2cceeb731950
equal deleted inserted replaced
45:e94ab812c0c8 46:73aef9705d6c
     1 """
       
     2     Template handler
       
     3 """
       
     4 
       
     5 # use Mako
       
     6 from mako import exceptions
       
     7 from mako.template import Template
       
     8 import mako.lookup
       
     9 
       
    10 # for http.ResponseError
       
    11 import http
       
    12 
       
    13 import helpers
       
    14 
       
    15 # path to template files
       
    16 TEMPLATE_DIR = "templates"
       
    17 
       
    18 # path to cached templates
       
    19 CACHE_DIR = "cache/templates"
       
    20 
       
    21 # template file extension
       
    22 TEMPLATE_EXT = "tmpl"
       
    23 
       
    24 class TemplateError (http.ResponseError) :
       
    25     """
       
    26         Raised by the template module functions
       
    27     """
       
    28 
       
    29     pass
       
    30 
       
    31 class TemplateLoader (mako.lookup.TemplateLookup) :
       
    32     """
       
    33         Our own specialization of mako's TemplateLookup
       
    34     """
       
    35 
       
    36     def __init__ (self, path, fileext=TEMPLATE_EXT, **env) :
       
    37         """
       
    38             Initialize to load templates located at path, with the given file extension.
       
    39 
       
    40             The given **env list is supplied to every template render
       
    41         """
       
    42 
       
    43         # store
       
    44         self.path = path
       
    45         self.fileext = fileext
       
    46         self.env = env
       
    47             
       
    48         # build the TemplateLookup
       
    49         super(TemplateLoader, self).__init__(directories=[path], module_directory=CACHE_DIR)
       
    50     
       
    51     @staticmethod
       
    52     def _render (tpl, env, params) :
       
    53         """
       
    54             Render the given template with given env/params, returning the output as a unicode string, or raising a TemplateError
       
    55         """
       
    56 
       
    57         # build the context from our superglobals, env, and params
       
    58         ctx = dict(
       
    59             h       = helpers,
       
    60         )
       
    61         ctx.update(env)
       
    62         ctx.update(params)
       
    63 
       
    64         try :
       
    65             return tpl.render_unicode(**ctx)
       
    66         
       
    67         # a template may render other templates
       
    68         except TemplateError :
       
    69             raise
       
    70 
       
    71         except :
       
    72             details = exceptions.text_error_template().render()
       
    73 
       
    74             raise TemplateError("Template render failed", status='500 Internal Server Error', details=details)
       
    75 
       
    76 
       
    77     def lookup (self, name) :
       
    78         """
       
    79             Looks up a template based on the bare "name", which does not include the path or file extension
       
    80         """
       
    81         
       
    82         try :
       
    83             return self.get_template("%s.%s" % (name, self.fileext))
       
    84 
       
    85         except :
       
    86             raise TemplateError("Template broken: %r" % (name, ), status='500 Internal Server Error', details=exceptions.text_error_template().render())
       
    87     
       
    88     def render (self, name, **params) :
       
    89         """
       
    90             Render a template, using lookup() on the given name
       
    91         """
       
    92 
       
    93         return self._render(self.lookup(name), self.env, params)
       
    94 
       
    95     def render_to_response (self, name, **params) :
       
    96         """
       
    97             Render a template, returning a http.Response object
       
    98         """
       
    99 
       
   100         return http.Response(self.render(name, **params))
       
   101 
       
   102     @classmethod
       
   103     def load (cls, path) :
       
   104         """
       
   105             Loads a template from a specific file
       
   106         """
       
   107 
       
   108         try :
       
   109             return Template(filename=path, module_directory=CACHE_DIR)
       
   110 
       
   111         except :
       
   112             raise TemplateError("Template broken: %r" % (path, ), status='500 Internal Server Error', details=exceptions.text_error_template().render())
       
   113     
       
   114     @classmethod
       
   115     def render_file (cls, path, **params) :
       
   116         """
       
   117             Render a template, using load() on the given path. No global environment vars are defined for the render.
       
   118         """
       
   119 
       
   120         return cls._render(cls.load(path), dict(), params)
       
   121 
       
   122     @classmethod
       
   123     def render_template (cls, template, **params) :
       
   124         """
       
   125             Render the given template object. No global environment vars are defined for the render.
       
   126         """
       
   127         
       
   128         return cls._render(template, dict(), params)