##// END OF EJS Templates
templater: lift parsed and compiled templates to generic data types...
Yuya Nishihara -
r28545:1d461ee2 default
parent child Browse files
Show More
@@ -177,9 +177,15 b' def _parsetemplate(tmpl, start, stop, qu'
177 177 raise error.ParseError(_("unterminated string"), start)
178 178 return parsed, pos
179 179
180 def compiletemplate(tmpl, context):
180 def parse(tmpl):
181 """Parse template string into tree"""
181 182 parsed, pos = _parsetemplate(tmpl, 0, len(tmpl))
182 return [compileexp(e, context, methods) for e in parsed]
183 assert pos == len(tmpl), 'unquoted template should be consumed'
184 return ('template', parsed)
185
186 def compiletemplate(tmpl, context):
187 """Parse and compile template string to (func, data) pair"""
188 return compileexp(parse(tmpl), context, methods)
183 189
184 190 def compileexp(exp, context, curmethods):
185 191 t = exp[0]
@@ -202,8 +208,10 b' def getlist(x):'
202 208 return [x]
203 209
204 210 def gettemplate(exp, context):
211 """Compile given template tree or load named template from map file;
212 returns (func, data) pair"""
205 213 if exp[0] == 'template':
206 return [compileexp(e, context, methods) for e in exp[1]]
214 return compileexp(exp, context, methods)
207 215 if exp[0] == 'symbol':
208 216 # unlike runsymbol(), here 'symbol' is always taken as template name
209 217 # even if it exists in mapping. this allows us to override mapping
@@ -308,11 +316,11 b' def runfilter(context, mapping, data):'
308 316
309 317 def buildmap(exp, context):
310 318 func, data = compileexp(exp[1], context, methods)
311 ctmpl = gettemplate(exp[2], context)
312 return (runmap, (func, data, ctmpl))
319 tfunc, tdata = gettemplate(exp[2], context)
320 return (runmap, (func, data, tfunc, tdata))
313 321
314 322 def runmap(context, mapping, data):
315 func, data, ctmpl = data
323 func, data, tfunc, tdata = data
316 324 d = func(context, mapping, data)
317 325 if util.safehasattr(d, 'itermaps'):
318 326 diter = d.itermaps()
@@ -330,7 +338,7 b' def runmap(context, mapping, data):'
330 338 if isinstance(i, dict):
331 339 lm.update(i)
332 340 lm['originalnode'] = mapping.get('node')
333 yield runtemplate(context, lm, ctmpl)
341 yield tfunc(context, lm, tdata)
334 342 else:
335 343 # v is not an iterable of dicts, this happen when 'key'
336 344 # has been fully expanded already and format is useless.
@@ -857,13 +865,13 b' class engine(object):'
857 865 if defaults is None:
858 866 defaults = {}
859 867 self._defaults = defaults
860 self._cache = {}
868 self._cache = {} # key: (func, data)
861 869
862 870 def _load(self, t):
863 871 '''load, parse, and cache a template'''
864 872 if t not in self._cache:
865 873 # put poison to cut recursion while compiling 't'
866 self._cache[t] = [(_runrecursivesymbol, t)]
874 self._cache[t] = (_runrecursivesymbol, t)
867 875 try:
868 876 self._cache[t] = compiletemplate(self._loader(t), self)
869 877 except: # re-raises
@@ -875,7 +883,8 b' class engine(object):'
875 883 '''Perform expansion. t is name of map element to expand.
876 884 mapping contains added elements for use during expansion. Is a
877 885 generator.'''
878 return _flatten(runtemplate(self, mapping, self._load(t)))
886 func, data = self._load(t)
887 return _flatten(func(self, mapping, data))
879 888
880 889 engines = {'default': engine}
881 890
General Comments 0
You need to be logged in to leave comments. Login now