templater: make the templating engine pluggable to some extent
authorDirkjan Ochtman <dirkjan@ochtman.nl>
Tue, 12 May 2009 12:05:19 +0200
changeset 8361 d8c5a7f25a40
parent 8360 acc202b71619
child 8362 bbc74c05b8a4
templater: make the templating engine pluggable to some extent
mercurial/templater.py
tests/test-template-engine
tests/test-template-engine.out
--- a/mercurial/templater.py	Tue May 12 12:04:05 2009 +0200
+++ b/mercurial/templater.py	Tue May 12 12:05:19 2009 +0200
@@ -105,6 +105,8 @@
                         v = self.filters[f](v)
                 yield v
 
+engines = {'default': engine}
+
 class templater(object):
 
     def __init__(self, mapfile, filters={}, defaults={}, cache={},
@@ -121,6 +123,7 @@
         self.filters.update(filters)
         self.defaults = defaults
         self.minchunk, self.maxchunk = minchunk, maxchunk
+        self.engines = {}
 
         if not mapfile:
             return
@@ -138,7 +141,10 @@
                     raise SyntaxError('%s: %s' %
                                       (conf.source('', key), inst.args[0]))
             else:
-                self.map[key] = os.path.join(self.base, val)
+                val = 'default', val
+                if ':' in val[1]:
+                    val = val[1].split(':', 1)
+                self.map[key] = val[0], os.path.join(self.base, val[1])
 
     def __contains__(self, key):
         return key in self.cache or key in self.map
@@ -147,14 +153,19 @@
         '''Get the template for the given template name. Use a local cache.'''
         if not t in self.cache:
             try:
-                self.cache[t] = file(self.map[t]).read()
+                self.cache[t] = open(self.map[t][1]).read()
             except IOError, inst:
                 raise IOError(inst.args[0], _('template file %s: %s') %
-                              (self.map[t], inst.args[1]))
+                              (self.map[t][1], inst.args[1]))
         return self.cache[t]
 
     def __call__(self, t, **map):
-        proc = engine(self.load, self.filters, self.defaults)
+        ttype = t in self.map and self.map[t][0] or 'default'
+        proc = self.engines.get(ttype)
+        if proc is None:
+            proc = engines[ttype](self.load, self.filters, self.defaults)
+            self.engines[ttype] = proc
+
         stream = proc.process(t, map)
         if self.minchunk:
             stream = util.increasingchunks(stream, min=self.minchunk,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-template-engine	Tue May 12 12:05:19 2009 +0200
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+cat > engine.py << EOF
+
+from mercurial import templater
+
+class mytemplater(object):
+    def __init__(self, loader, filters, defaults):
+        self.loader = loader
+
+    def process(self, t, map):
+        tmpl = self.loader(t)
+        for k, v in map.iteritems():
+            v = templater.stringify(v)
+            tmpl = tmpl.replace('{{%s}}' % k, v)
+        yield tmpl
+
+templater.engines['my'] = mytemplater
+EOF
+
+hg init test
+echo '[extensions]' > test/.hg/hgrc
+echo "engine = $PWD/engine.py" >> test/.hg/hgrc
+
+cd test
+cat > mymap << EOF
+changeset = my:changeset.txt
+EOF
+
+cat > changeset.txt << EOF
+{{rev}} {{node}} {{author}}
+EOF
+
+hg ci -Ama
+hg log --style=./mymap
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-template-engine.out	Tue May 12 12:05:19 2009 +0200
@@ -0,0 +1,3 @@
+adding changeset.txt
+adding mymap
+0 97e5f848f0936960273bbf75be6388cd0350a32b test