############################################################################## # @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 ""