Created
February 19, 2011 15:59
-
-
Save vbmendes/835142 to your computer and use it in GitHub Desktop.
Make it easier to create templatetags with parameters.
This file contains 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.template import Node, TemplateSyntaxError | |
from django.template import resolve_variable | |
from django.utils.encoding import smart_str | |
class BaseNode(Node): | |
def __init__(self, **kwargs): | |
self.parsed = kwargs | |
@classmethod | |
def parse(cls, parser, token): | |
raise NotImplementedError | |
def render(self, context): | |
return self.render_vars(context, **self.resolve_vars_in_context(context)) | |
def render_vars(self, context, **kwargs): | |
raise NotImplementedError | |
def resolve_vars_in_context(self, context): | |
resolved = {} | |
for var_name, var_value in self.parsed.items(): | |
if var_name == 'args': | |
for i, arg_value in enumerate(var_value): | |
var_value[i] = resolve_variable(arg_value, context) | |
elif var_name == 'kwargs': | |
for arg_name, arg_value in var_value.items(): | |
var_value[arg_name] = resolve_variable(arg_value, context) | |
else: | |
if isinstance(var_value, basestring): | |
resolved_value = resolve_variable(var_value, context) | |
else: | |
resolved_value = var_value | |
resolved[var_name] = resolved_value | |
return resolved | |
class ArgsKwargsNode(BaseNode): | |
args_names = ('container', 'quantity') | |
@classmethod | |
def parse(cls, parser, token): #@UnusedVariable | |
bits = token.contents.split() | |
tag_name = bits[0] | |
bits = bits[1:] | |
len_bits = len(bits) | |
len_args_names = len(cls.args_names) | |
kwargs = { | |
'args': [], | |
'kwargs': {}, | |
} | |
found_kwarg = False | |
for i, bit in enumerate(bits): | |
bit_kwarg = bit.split('=') | |
if len(bit_kwarg) > 1: | |
found_kwarg = True | |
arg_value = "=".join(bit_kwarg[1:]) | |
arg_name = bit_kwarg[0] | |
if arg_name in kwargs.keys() or arg_name in kwargs['kwargs'].keys(): | |
raise TemplateSyntaxError("%s arg appears twice in %s." % (arg_name, tag_name)) | |
if arg_name not in cls.args_names: | |
kwargs['kwargs'][smart_str(arg_name)] = arg_value | |
break | |
elif found_kwarg: | |
raise TemplateSyntaxError("%s has args after kwargs." % arg_name) | |
else: | |
arg_value = bit_kwarg[0] | |
if i >= len_args_names: | |
kwargs['args'].append(arg_value) | |
break | |
else: | |
arg_name = cls.args_names[i] | |
kwargs[smart_str(arg_name)] = arg_value | |
return cls(**kwargs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment