282 # even if it exists in mapping. this allows us to override mapping |
282 # even if it exists in mapping. this allows us to override mapping |
283 # by web templates, e.g. 'changelogtag' is redefined in map file. |
283 # by web templates, e.g. 'changelogtag' is redefined in map file. |
284 return context._load(exp[1]) |
284 return context._load(exp[1]) |
285 raise error.ParseError(_("expected template specifier")) |
285 raise error.ParseError(_("expected template specifier")) |
286 |
286 |
|
287 def findsymbolicname(arg): |
|
288 """Find symbolic name for the given compiled expression; returns None |
|
289 if nothing found reliably""" |
|
290 while True: |
|
291 func, data = arg |
|
292 if func is runsymbol: |
|
293 return data |
|
294 elif func is runfilter: |
|
295 arg = data[0] |
|
296 else: |
|
297 return None |
|
298 |
287 def evalfuncarg(context, mapping, arg): |
299 def evalfuncarg(context, mapping, arg): |
288 func, data = arg |
300 func, data = arg |
289 # func() may return string, generator of strings or arbitrary object such |
301 # func() may return string, generator of strings or arbitrary object such |
290 # as date tuple, but filter does not want generator. |
302 # as date tuple, but filter does not want generator. |
291 thing = func(context, mapping, data) |
303 thing = func(context, mapping, data) |
385 arg, filt = data |
397 arg, filt = data |
386 thing = evalfuncarg(context, mapping, arg) |
398 thing = evalfuncarg(context, mapping, arg) |
387 try: |
399 try: |
388 return filt(thing) |
400 return filt(thing) |
389 except (ValueError, AttributeError, TypeError): |
401 except (ValueError, AttributeError, TypeError): |
390 if isinstance(arg[1], tuple): |
402 sym = findsymbolicname(arg) |
391 dt = arg[1][1] |
403 if sym: |
|
404 msg = (_("template filter '%s' is not compatible with keyword '%s'") |
|
405 % (filt.func_name, sym)) |
392 else: |
406 else: |
393 dt = arg[1] |
407 msg = _("incompatible use of template filter '%s'") % filt.func_name |
394 raise error.Abort(_("template filter '%s' is not compatible with " |
408 raise error.Abort(msg) |
395 "keyword '%s'") % (filt.func_name, dt)) |
|
396 |
409 |
397 def buildmap(exp, context): |
410 def buildmap(exp, context): |
398 func, data = compileexp(exp[1], context, methods) |
411 func, data = compileexp(exp[1], context, methods) |
399 tfunc, tdata = gettemplate(exp[2], context) |
412 tfunc, tdata = gettemplate(exp[2], context) |
400 return (runmap, (func, data, tfunc, tdata)) |
413 return (runmap, (func, data, tfunc, tdata)) |