##############################################################################
#
@register.tag(name = 'method_arg')
def method_arg(parser, token):
"""
This tag allows us to call the given method with the given
argument and set the resultant value to a variable in our context.
ie: {% method_arg foo bar user as post %} would result in the
variable 'post' getting the result of evaluating foo.bar(user).
If the argument is surrounded by quotes, then it is considered a
string and not a variable to be resolved.
"""
try:
tag_name, var, method_name, arg, ign, dst = token.split_contents()
except ValueError:
raise template.TemplateSyntaxError, "%r requires arguments in the " \
"format of as ."
if ign.lower() != "as":
raise template.TemplateSyntaxError, "%r requires arguments in the " \
"format of as ."
return MethodArgNode(var, method_name, arg, dst)
class MethodArgNode(template.Node):
"""
The template node sub-class that does the work of looking up the
method you wish to invoke in your template, resolving the variable
to pass to it and setting the resultant value in the template's
context.
"""
def __init__(self, var, method_name, arg, dst):
self.var = var
self.method_name = method_name
self.arg = arg
self.dest = dst
def render(self, context):
try:
obj = resolve_variable(self.var, context)
if hasattr(obj, self.method_name) and \
isinstance(getattr(obj, self.method_name), MethodType):
if self.arg[0] == self.arg[-1] and self.arg[0] in ('"', "'"):
context[self.dest] = \
getattr(obj, self.method_name)(self.arg[1:-1])
else:
context[self.dest] = getattr(obj, self.method_name)\
(resolve_variable(self.arg, context))
except:
# render() should never raise any exception. If something goes
# wrong we need to log it somewhere else, not chuck it up the
# call stack.
#
raise
pass
return ""