Mercurial > public > mercurial-scm > hg-stable
diff mercurial/templater.py @ 35472:32c278eb876f
templater: keep default resources per template engine (API)
This allows us to register a repo object as a resource in hgweb template,
without loosing '{repo}' symbol:
symbol('repo') -> mapping['repo'] (n/a) -> defaults['repo']
resource('repo') -> mapping['repo'] (n/a) -> resources['repo']
I'm thinking of redesigning the templatekw API to take (context, mapping)
in place of **(context._resources + mapping), but that will be a big change
and not implemented yet.
props['templ'] is ported to the resources dict as an example.
.. api::
mapping does not contain all template resources. use context.resource()
in template functions.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Thu, 21 Dec 2017 21:29:06 +0900 |
parents | d6cfa722b044 |
children | a33be093ec62 |
line wrap: on
line diff
--- a/mercurial/templater.py Thu Dec 21 21:03:25 2017 +0900 +++ b/mercurial/templater.py Thu Dec 21 21:29:06 2017 +0900 @@ -393,7 +393,11 @@ except TemplateNotFound: v = default if callable(v): - return v(**pycompat.strkwargs(mapping)) + # TODO: templatekw functions will be updated to take (context, mapping) + # pair instead of **props + props = context._resources.copy() + props.update(mapping) + return v(**props) return v def buildtemplate(exp, context): @@ -657,7 +661,10 @@ ctx = context.resource(mapping, 'ctx') m = ctx.match([raw]) files = list(ctx.matches(m)) - return templatekw.showlist("file", files, mapping) + # TODO: pass (context, mapping) pair to keyword function + props = context._resources.copy() + props.update(mapping) + return templatekw.showlist("file", files, props) @templatefunc('fill(text[, width[, initialident[, hangindent]]])') def fill(context, mapping, args): @@ -878,7 +885,10 @@ if len(args) == 1: pattern = evalstring(context, mapping, args[0]) - return templatekw.showlatesttags(pattern, **pycompat.strkwargs(mapping)) + # TODO: pass (context, mapping) pair to keyword function + props = context._resources.copy() + props.update(mapping) + return templatekw.showlatesttags(pattern, **pycompat.strkwargs(props)) @templatefunc('localdate(date[, tz])') def localdate(context, mapping, args): @@ -1062,8 +1072,11 @@ revs = list(revs) revsetcache[raw] = revs + # TODO: pass (context, mapping) pair to keyword function + props = context._resources.copy() + props.update(mapping) return templatekw.showrevslist("revision", revs, - **pycompat.strkwargs(mapping)) + **pycompat.strkwargs(props)) @templatefunc('rstdoc(text, style)') def rstdoc(context, mapping, args): @@ -1290,14 +1303,18 @@ filter uses function to transform value. syntax is {key|filter1|filter2|...}.''' - def __init__(self, loader, filters=None, defaults=None, aliases=()): + def __init__(self, loader, filters=None, defaults=None, resources=None, + aliases=()): self._loader = loader if filters is None: filters = {} self._filters = filters if defaults is None: defaults = {} + if resources is None: + resources = {} self._defaults = defaults + self._resources = resources self._aliasmap = _aliasrules.buildmap(aliases) self._cache = {} # key: (func, data) @@ -1311,7 +1328,12 @@ def resource(self, mapping, key): """Return internal data (e.g. cache) used for keyword/function evaluation""" - return mapping[key] + v = mapping.get(key) + if v is None: + v = self._resources.get(key) + if v is None: + raise KeyError + return v def _load(self, t): '''load, parse, and cache a template''' @@ -1406,17 +1428,21 @@ class templater(object): - def __init__(self, filters=None, defaults=None, cache=None, aliases=(), - minchunk=1024, maxchunk=65536): + def __init__(self, filters=None, defaults=None, resources=None, + cache=None, aliases=(), minchunk=1024, maxchunk=65536): '''set up template engine. filters is dict of functions. each transforms a value into another. defaults is dict of default map definitions. + resources is dict of internal data (e.g. cache), which are inaccessible + from user template. aliases is list of alias (name, replacement) pairs. ''' if filters is None: filters = {} if defaults is None: defaults = {} + if resources is None: + resources = {} if cache is None: cache = {} self.cache = cache.copy() @@ -1424,15 +1450,17 @@ self.filters = templatefilters.filters.copy() self.filters.update(filters) self.defaults = defaults + self._resources = {'templ': self} + self._resources.update(resources) self._aliases = aliases self.minchunk, self.maxchunk = minchunk, maxchunk self.ecache = {} @classmethod - def frommapfile(cls, mapfile, filters=None, defaults=None, cache=None, - minchunk=1024, maxchunk=65536): + def frommapfile(cls, mapfile, filters=None, defaults=None, resources=None, + cache=None, minchunk=1024, maxchunk=65536): """Create templater from the specified map file""" - t = cls(filters, defaults, cache, [], minchunk, maxchunk) + t = cls(filters, defaults, resources, cache, [], minchunk, maxchunk) cache, tmap, aliases = _readmapfile(mapfile) t.cache.update(cache) t.map = tmap @@ -1469,7 +1497,7 @@ except KeyError: raise error.Abort(_('invalid template engine: %s') % ttype) self.ecache[ttype] = ecls(self.load, self.filters, self.defaults, - self._aliases) + self._resources, self._aliases) proc = self.ecache[ttype] stream = proc.process(t, mapping)