templater: use named function to expand template against mapping dict (API)
And replace __call__(t, **mapping) in favor of generate(t, mapping). I prefer
a named function here since the templater isn't a simple function-like object.
.. api::
The templater is no longer callable. Use ``templater.generate(t, mapping)``
instead of ``templater(t, **pycompat.strkwargs(mapping))``.
--- a/mercurial/hgweb/hgweb_mod.py Mon Mar 19 21:09:23 2018 +0900
+++ b/mercurial/hgweb/hgweb_mod.py Fri Mar 16 21:39:32 2018 +0900
@@ -198,7 +198,8 @@
def sendtemplate(self, name, **kwargs):
"""Helper function to send a response generated from a template."""
- self.res.setbodygen(self.tmpl(name, **kwargs))
+ kwargs = pycompat.byteskwargs(kwargs)
+ self.res.setbodygen(self.tmpl.generate(name, kwargs))
return self.res.sendresponse()
class hgweb(object):
--- a/mercurial/hgweb/hgwebdir_mod.py Mon Mar 19 21:09:23 2018 +0900
+++ b/mercurial/hgweb/hgwebdir_mod.py Fri Mar 16 21:39:32 2018 +0900
@@ -452,12 +452,12 @@
# prefixes not found
res.status = '404 Not Found'
- res.setbodygen(tmpl('notfound', repo=virtual))
+ res.setbodygen(tmpl.generate('notfound', {'repo': virtual}))
return res.sendresponse()
except ErrorResponse as e:
res.status = statusmessage(e.code, pycompat.bytestr(e))
- res.setbodygen(tmpl('error', error=e.message or ''))
+ res.setbodygen(tmpl.generate('error', {'error': e.message or ''}))
return res.sendresponse()
finally:
tmpl = None
@@ -485,15 +485,15 @@
self.stripecount, sortcolumn=sortcolumn,
descending=descending, subdir=subdir)
- res.setbodygen(tmpl(
- 'index',
- entries=entries,
- subdir=subdir,
- pathdef=hgweb_mod.makebreadcrumb('/' + subdir, self.prefix),
- sortcolumn=sortcolumn,
- descending=descending,
- **dict(sort)))
-
+ mapping = {
+ 'entries': entries,
+ 'subdir': subdir,
+ 'pathdef': hgweb_mod.makebreadcrumb('/' + subdir, self.prefix),
+ 'sortcolumn': sortcolumn,
+ 'descending': descending,
+ }
+ mapping.update(sort)
+ res.setbodygen(tmpl.generate('index', mapping))
return res.sendresponse()
def templater(self, req, nonce):
--- a/mercurial/hgweb/webcommands.py Mon Mar 19 21:09:23 2018 +0900
+++ b/mercurial/hgweb/webcommands.py Fri Mar 16 21:39:32 2018 +0900
@@ -294,12 +294,13 @@
files = webutil.listfilediffs(web.tmpl, ctx.files(), n,
web.maxfiles)
- yield web.tmpl(
- 'searchentry',
- parity=next(parity),
- changelogtag=showtags,
- files=files,
- **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))
+ lm = webutil.commonentry(web.repo, ctx)
+ lm.update({
+ 'parity': next(parity),
+ 'changelogtag': showtags,
+ 'files': files,
+ })
+ yield web.tmpl.generate('searchentry', lm)
if count >= revcount:
break
@@ -719,12 +720,12 @@
if count > 10: # limit to 10 tags
break
- yield web.tmpl(
- 'tagentry',
- parity=next(parity),
- tag=k,
- node=hex(n),
- date=web.repo[n].date())
+ yield web.tmpl.generate('tagentry', {
+ 'parity': next(parity),
+ 'tag': k,
+ 'node': hex(n),
+ 'date': web.repo[n].date(),
+ })
def bookmarks(**map):
parity = paritygen(web.stripecount)
@@ -745,11 +746,9 @@
revs = web.repo.changelog.revs(start, end - 1)
for i in revs:
ctx = web.repo[i]
-
- l.append(web.tmpl(
- 'shortlogentry',
- parity=next(parity),
- **pycompat.strkwargs(webutil.commonentry(web.repo, ctx))))
+ lm = webutil.commonentry(web.repo, ctx)
+ lm['parity'] = next(parity)
+ l.append(web.tmpl.generate('shortlogentry', lm))
for entry in reversed(l):
yield entry
--- a/mercurial/hgweb/webutil.py Mon Mar 19 21:09:23 2018 +0900
+++ b/mercurial/hgweb/webutil.py Fri Mar 16 21:39:32 2018 +0900
@@ -243,12 +243,18 @@
return branches
def showtag(repo, tmpl, t1, node=nullid, **args):
+ args = pycompat.byteskwargs(args)
for t in repo.nodetags(node):
- yield tmpl(t1, tag=t, **args)
+ lm = args.copy()
+ lm['tag'] = t
+ yield tmpl.generate(t1, lm)
def showbookmark(repo, tmpl, t1, node=nullid, **args):
+ args = pycompat.byteskwargs(args)
for t in repo.nodebookmarks(node):
- yield tmpl(t1, bookmark=t, **args)
+ lm = args.copy()
+ lm['bookmark'] = t
+ yield tmpl.generate(t1, lm)
def branchentries(repo, stripecount, limit=0):
tips = []
@@ -443,9 +449,12 @@
parity = paritygen(web.stripecount)
for blockno, f in enumerate(ctx.files()):
template = 'filenodelink' if f in ctx else 'filenolink'
- files.append(web.tmpl(template,
- node=ctx.hex(), file=f, blockno=blockno + 1,
- parity=next(parity)))
+ files.append(web.tmpl.generate(template, {
+ 'node': ctx.hex(),
+ 'file': f,
+ 'blockno': blockno + 1,
+ 'parity': next(parity),
+ }))
basectx = basechangectx(web.repo, web.req)
if basectx is None:
@@ -476,9 +485,9 @@
def listfilediffs(tmpl, files, node, max):
for f in files[:max]:
- yield tmpl('filedifflink', node=hex(node), file=f)
+ yield tmpl.generate('filedifflink', {'node': hex(node), 'file': f})
if len(files) > max:
- yield tmpl('fileellipses')
+ yield tmpl.generate('fileellipses', {})
def diffs(web, ctx, basectx, files, style, linerange=None,
lineidprefix=''):
@@ -494,12 +503,12 @@
ltype = "difflineat"
else:
ltype = "diffline"
- yield web.tmpl(
- ltype,
- line=l,
- lineno=lineno,
- lineid=lineidprefix + "l%s" % difflineno,
- linenumber="% 8s" % difflineno)
+ yield web.tmpl.generate(ltype, {
+ 'line': l,
+ 'lineno': lineno,
+ 'lineid': lineidprefix + "l%s" % difflineno,
+ 'linenumber': "% 8s" % difflineno,
+ })
repo = web.repo
if files:
@@ -524,8 +533,11 @@
continue
lines.extend(hunklines)
if lines:
- yield web.tmpl('diffblock', parity=next(parity), blockno=blockno,
- lines=prettyprintlines(lines, blockno))
+ yield web.tmpl.generate('diffblock', {
+ 'parity': next(parity),
+ 'blockno': blockno,
+ 'lines': prettyprintlines(lines, blockno),
+ })
def compare(tmpl, context, leftlines, rightlines):
'''Generator function that provides side-by-side comparison data.'''
@@ -535,15 +547,16 @@
lineid += rightlineno and ("r%d" % rightlineno) or ''
llno = '%d' % leftlineno if leftlineno else ''
rlno = '%d' % rightlineno if rightlineno else ''
- return tmpl('comparisonline',
- type=type,
- lineid=lineid,
- leftlineno=leftlineno,
- leftlinenumber="% 6s" % llno,
- leftline=leftline or '',
- rightlineno=rightlineno,
- rightlinenumber="% 6s" % rlno,
- rightline=rightline or '')
+ return tmpl.generate('comparisonline', {
+ 'type': type,
+ 'lineid': lineid,
+ 'leftlineno': leftlineno,
+ 'leftlinenumber': "% 6s" % llno,
+ 'leftline': leftline or '',
+ 'rightlineno': rightlineno,
+ 'rightlinenumber': "% 6s" % rlno,
+ 'rightline': rightline or '',
+ })
def getblock(opcodes):
for type, llo, lhi, rlo, rhi in opcodes:
@@ -573,10 +586,11 @@
s = difflib.SequenceMatcher(None, leftlines, rightlines)
if context < 0:
- yield tmpl('comparisonblock', lines=getblock(s.get_opcodes()))
+ yield tmpl.generate('comparisonblock',
+ {'lines': getblock(s.get_opcodes())})
else:
for oc in s.get_grouped_opcodes(n=context):
- yield tmpl('comparisonblock', lines=getblock(oc))
+ yield tmpl.generate('comparisonblock', {'lines': getblock(oc)})
def diffstatgen(ctx, basectx):
'''Generator function that provides the diffstat data.'''
@@ -610,9 +624,15 @@
template = 'diffstatlink' if filename in files else 'diffstatnolink'
total = adds + removes
fileno += 1
- yield tmpl(template, node=ctx.hex(), file=filename, fileno=fileno,
- total=total, addpct=pct(adds), removepct=pct(removes),
- parity=next(parity))
+ yield tmpl.generate(template, {
+ 'node': ctx.hex(),
+ 'file': filename,
+ 'fileno': fileno,
+ 'total': total,
+ 'addpct': pct(adds),
+ 'removepct': pct(removes),
+ 'parity': next(parity),
+ })
class sessionvars(object):
def __init__(self, vars, start='?'):
--- a/mercurial/templatekw.py Mon Mar 19 21:09:23 2018 +0900
+++ b/mercurial/templatekw.py Fri Mar 16 21:39:32 2018 +0900
@@ -478,7 +478,7 @@
mhex = hex(mnode)
mapping = mapping.copy()
mapping.update({'rev': mrev, 'node': mhex})
- f = templ('manifest', **pycompat.strkwargs(mapping))
+ f = templ.generate('manifest', mapping)
# TODO: perhaps 'ctx' should be dropped from mapping because manifest
# rev and node are completely different from changeset's.
return _mappable(f, None, f, lambda x: {'rev': mrev, 'node': mhex})
--- a/mercurial/templater.py Mon Mar 19 21:09:23 2018 +0900
+++ b/mercurial/templater.py Fri Mar 16 21:39:32 2018 +0900
@@ -770,11 +770,11 @@
def render(self, t, mapping):
"""Render the specified named template and return result as string"""
- mapping = pycompat.strkwargs(mapping)
- return templateutil.stringify(self(t, **mapping))
+ return templateutil.stringify(self.generate(t, mapping))
- def __call__(self, t, **mapping):
- mapping = pycompat.byteskwargs(mapping)
+ def generate(self, t, mapping):
+ """Return a generator that renders the specified named template and
+ yields chunks"""
ttype = t in self.map and self.map[t][0] or 'default'
if ttype not in self.ecache:
try:
--- a/mercurial/templateutil.py Mon Mar 19 21:09:23 2018 +0900
+++ b/mercurial/templateutil.py Fri Mar 16 21:39:32 2018 +0900
@@ -184,13 +184,12 @@
expand 'end_foos'.
'''
- strmapping = pycompat.strkwargs(mapping)
if not plural:
plural = name + 's'
if not values:
noname = 'no_' + plural
if noname in templ:
- yield templ(noname, **strmapping)
+ yield templ.generate(noname, mapping)
return
if name not in templ:
if isinstance(values[0], bytes):
@@ -203,7 +202,7 @@
return
startname = 'start_' + plural
if startname in templ:
- yield templ(startname, **strmapping)
+ yield templ.generate(startname, mapping)
vmapping = mapping.copy()
def one(v, tag=name):
try:
@@ -218,7 +217,7 @@
vmapping[a] = b
except (TypeError, ValueError):
vmapping[name] = v
- return templ(tag, **pycompat.strkwargs(vmapping))
+ return templ.generate(tag, vmapping)
lastname = 'last_' + name
if lastname in templ:
last = values.pop()
@@ -230,7 +229,7 @@
yield one(last, tag=lastname)
endname = 'end_' + plural
if endname in templ:
- yield templ(endname, **strmapping)
+ yield templ.generate(endname, mapping)
def stringify(thing):
"""Turn values into bytes by converting into text and concatenating them"""