[RFC] [PATCH] Support arguments in template expandos
Rocco Rutte
pdmef at gmx.net
Thu May 7 11:08:36 CDT 2009
Hi,
in order to provide different messages for different terms instead of
just "(none)" through the nonempty template filter, I extended the
templater to support arguments for keys and filters like so:
{key ["arg1" ["arg2" ...]]|filter1 ["arg1" ["arg2" ...]]|...}
Arguments for filters could be used like this:
{desc|...|nonempty "no description"}
Arguments for keys can be used like this:
{tr "changeset"}
to translate the term changeset (i.e. make hgweb internationalized --
though I have no idea how to manage translation files, but using "tr"
works).
The most ugly parts currently are:
- the arguments for keys are passed in the map with key = 'args'
- the 'tr' key is hardcoded across all templater instances
For filters, the patch allows both the new and new python syntax (so I
don't have to touch too many places for just a proof-of-concept).
The patch is against current crew. Comments? Ideas? Suggestions?
Rocco
diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -41,8 +41,11 @@ class engine(object):
filter uses function to transform value. syntax is
{key|filter1|filter2|...}.'''
- template_re = re.compile(r"(?:(?:#(?=[\w\|%]+#))|(?:{(?=[\w\|%]+})))"
- r"(\w+)(?:(?:%(\w+))|((?:\|\w+)*))[#}]")
+ template_re = re.compile(r"(?:(?:#(?=[\w\s\"\|%]+#))|(?:{(?=[\w\s\"\|%]+})))"
+ r"(\w+(?:\s\"[^\"]*\")*)(?:(?:%(\w+(?:\s\"[^\"]*\")*))|"
+ r"((?:\|\w+(?:\s\"[^\"]*\")*)*))[#}]")
+
+ args_re = re.compile(r"\"\s\"")
def __init__(self, loader, filters={}, defaults={}):
self.loader = loader
@@ -71,6 +74,15 @@ class engine(object):
def _process(self, tmpl, map):
'''Render a template. Returns a generator.'''
+
+ def _splitargs(s):
+ key = s.split(' ')[0]
+ args = [s[len(key):]]
+ if '"' in args[0]:
+ args = self.args_re.split(args[0])
+ args = [a.lstrip(' ').lstrip('"').rstrip('"') for a in args]
+ return key, args
+
while tmpl:
m = self.template_re.search(tmpl)
if not m:
@@ -84,11 +96,13 @@ class engine(object):
yield tmpl[:start]
tmpl = tmpl[end:]
+ key, args = _splitargs(key)
if key in map:
v = map[key]
else:
v = self.defaults.get(key, "")
if callable(v):
+ map['args'] = args
v = v(**map)
if format:
if not hasattr(v, '__iter__'):
@@ -101,9 +115,16 @@ class engine(object):
else:
if fl:
for f in fl.split("|")[1:]:
- v = self.filters[f](v)
+ key, args = _splitargs(f)
+ try:
+ v = self.filters[key](v, args)
+ except TypeError:
+ v = self.filters[key](v)
yield v
+def translate(**args):
+ return ' '.join([_(a) for a in args['args']])
+
class templater(object):
def __init__(self, mapfile, filters={}, defaults={}, cache={},
@@ -120,6 +141,8 @@ class templater(object):
self.defaults = defaults
self.minchunk, self.maxchunk = minchunk, maxchunk
+ self.defaults['tr'] = translate
+
if not mapfile:
return
if not os.path.exists(mapfile):
More information about the Mercurial-devel
mailing list