changeset 4743:2d6959f1d2df

templating: proof of concept for Jinja2 support. Select 'jinja2' template_engine in config and place .html templates into html/jinja2
author anatoly techtonik <techtonik@gmail.com>
date Thu, 17 Jan 2013 15:21:54 +0300
parents 9cc6d463cfbe
children 39663d048312
files CHANGES.txt roundup/cgi/engine_jinja2.py roundup/cgi/templating.py
diffstat 3 files changed, 107 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES.txt	Thu Jan 17 09:08:50 2013 +0300
+++ b/CHANGES.txt	Thu Jan 17 15:21:54 2013 +0300
@@ -13,6 +13,9 @@
   limiting the responsibility of Loaders to compilation and rendering.
   Internally, templating.find_template is replaced with
   client.selectTemplate (anatoly techtonik)
+- Experimental proof of concept code for Jinja2 templating engine.
+  Select 'jinja2' template_engine in config and place templates into 
+  html/jinja2 to play with (anatoly techtonik)
 
 Fixed:
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/roundup/cgi/engine_jinja2.py	Thu Jan 17 15:21:54 2013 +0300
@@ -0,0 +1,93 @@
+"""
+Experimental Jinja2 support for Roundup. It will become less
+experimental when it is completely clear what information is
+passed to template, and when the info is limited to the sane
+minimal set (to avoid Roundup state changes from template).
+
+[ ] fallback mechanizm to use multiple templating engines in
+    parallel and aid in incremental translation from one
+    engine to another
+
+[ ] define a place for templates
+    probably
+      TRACKER_HOME/templates/jinja2
+    with
+      TRACKER_HOME/templates/INFO.txt
+        describing how the dir was created, for example
+          "This is a copy of 'classic' template from ..."
+        also template fallback mechanizm for multi-engine
+          configuration
+    [ ] backward compatibility - if no engine is explicitly
+          specified, use TRACKER_HOME/html directory
+    [ ] copy TEMPLATES-INFO.txt to INFO.txt
+      [ ] implement VERSION file in environment for auto
+          upgrade
+[ ] figure out what to do with autoescaping - it is disabled
+    by default in Jinja2
+
+[ ] precompileTemplates is a stub
+
+[ ] add {{ debug() }} dumper to inspect available variables
+    https://github.com/mitsuhiko/jinja2/issues/174
+"""
+
+import jinja2
+
+# http://jinja.pocoo.org/docs/api/#loaders
+
+from roundup.cgi.templating import context, LoaderBase, TemplateBase
+
+class Jinja2Loader(LoaderBase):
+    def __init__(self, dir):
+        jinjadir = dir + '/jinja2'
+        # [ ] separate configuration when multiple loaders are used
+        print "Jinja2 templates:", jinjadir
+        self._env = jinja2.Environment(
+                        loader=jinja2.FileSystemLoader(jinjadir)
+                    )
+
+    def check(self, tplname):
+        print tplname
+        try:
+            print self._env.get_template(tplname + '.html')
+        except jinja2.TemplateNotFound:
+            return
+        else:
+            return True
+
+    def load(self, tplname):
+        #src, filename = self.check(tplname)
+        return Jinja2ProxyPageTemplate(self._env.get_template(tplname + '.html'))
+
+    def precompileTemplates(self):
+        pass
+
+class Jinja2ProxyPageTemplate(TemplateBase):
+    def __init__(self, template):
+        self._tpl = template
+
+    def render(self, client, classname, request, **options):
+        # [ ] limit the information passed to the minimal necessary set
+        c = context(client, self, classname, request)
+        '''c.update({'options': options})
+
+        def translate(msgid, domain=None, mapping=None, default=None):
+            result = client.translator.translate(domain, msgid,
+                         mapping=mapping, default=default)
+            return unicode(result, client.translator.OUTPUT_ENCODING)
+
+        output = self._pt.render(None, translate, **c)
+        return output.encode(client.charset)
+        '''
+        return self._tpl.render(c)
+
+    def __getitem__(self, name):
+        # [ ] figure out what are these for
+        raise NotImplemented
+        #return self._pt[name]
+
+    def __getattr__(self, name):
+        # [ ] figure out what are these for
+        raise NotImplemented
+        #return getattr(self._pt, name)
+
--- a/roundup/cgi/templating.py	Thu Jan 17 09:08:50 2013 +0300
+++ b/roundup/cgi/templating.py	Thu Jan 17 15:21:54 2013 +0300
@@ -77,6 +77,10 @@
 
 class LoaderBase:
     """ Base for engine-specific template Loader class."""
+    def __init__(self, dir):
+        # loaders are given the template directory as a first argument
+        pass
+
     def precompileTemplates(self):
         """ Go through a directory and precompile all the templates therein
         """
@@ -118,13 +122,17 @@
         except NoTemplate, message:
             raise KeyError, message
 
+class TemplateBase:
+    content_type = 'text/html'
 
 def get_loader(dir, engine_name):
     if engine_name == 'chameleon':
-        import engine_chameleon as engine
+        from engine_chameleon import Loader
+    elif engine_name == 'jinja2':
+        from engine_jinja2 import Jinja2Loader as Loader
     else:
-        import engine_zopetal as engine
-    return engine.Loader(dir)
+        from engine_zopetal import Loader
+    return Loader(dir)
 
 def context(client, template=None, classname=None, request=None):
     """Return the rendering context dictionary

Roundup Issue Tracker: http://roundup-tracker.org/