Created
November 17, 2014 23:44
-
-
Save natevw/f14812604be62c073461 to your computer and use it in GitHub Desktop.
register.simple_assignment_tag — custom Django template tag helper where result can be output directly *or* assigned as caller chooses. See https://gist.github.com/natevw/c30cd4f0c27323e3c275 for a (commented out) example of usage.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django import template | |
class Library(template.Library): | |
def simple_assignment_tag(self, func=None, takes_context=None, name=None): | |
''' | |
Like assignment_tag but when "as" not provided, falls back to simple_tag behavior! | |
NOTE: this is based on Django's assignment_tag implementation, modified as needed. | |
''' | |
# (nvw) imports necessary to match original context | |
from django.template.base import TemplateSyntaxError, TagHelperNode, parse_bits | |
from inspect import getargspec | |
def dec(func): | |
params, varargs, varkw, defaults = getargspec(func) | |
# (nvw) added from Django's simple_tag implementation | |
class SimpleNode(TagHelperNode): | |
def render(self, context): | |
resolved_args, resolved_kwargs = self.get_resolved_arguments(context) | |
return func(*resolved_args, **resolved_kwargs) | |
class AssignmentNode(TagHelperNode): | |
def __init__(self, takes_context, args, kwargs, target_var): | |
super(AssignmentNode, self).__init__(takes_context, args, kwargs) | |
self.target_var = target_var | |
def render(self, context): | |
resolved_args, resolved_kwargs = self.get_resolved_arguments(context) | |
context[self.target_var] = func(*resolved_args, **resolved_kwargs) | |
return '' | |
function_name = (name or | |
getattr(func, '_decorated_function', func).__name__) | |
def compile_func(parser, token): | |
bits = token.split_contents()[1:] | |
# if len(bits) < 2 or bits[-2] != 'as': | |
# raise TemplateSyntaxError( | |
# "'%s' tag takes at least 2 arguments and the " | |
# "second last argument must be 'as'" % function_name) | |
# (nvw) replaced above choose between AssignmentNode or SimpleNode | |
if bits[-2] == 'as': | |
target_var = bits[-1] | |
bits = bits[:-2] | |
args, kwargs = parse_bits(parser, bits, params, | |
varargs, varkw, defaults, takes_context, function_name) | |
return AssignmentNode(takes_context, args, kwargs, target_var) | |
else: | |
args, kwargs = parse_bits(parser, bits, params, | |
varargs, varkw, defaults, takes_context, function_name) | |
return SimpleNode(takes_context, args, kwargs) | |
compile_func.__doc__ = func.__doc__ | |
self.tag(function_name, compile_func) | |
return func | |
if func is None: | |
# @register.assignment_tag(...) | |
return dec | |
elif callable(func): | |
# @register.assignment_tag | |
return dec(func) | |
else: | |
raise TemplateSyntaxError("Invalid arguments provided to assignment_tag") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@natevw thanks for this really great. Would like to use this in a BSD-licensed project (Wooey) is that acceptable?