Skip to content

Instantly share code, notes, and snippets.

@vbmendes
Created February 19, 2011 15:59
Show Gist options
  • Save vbmendes/835142 to your computer and use it in GitHub Desktop.
Save vbmendes/835142 to your computer and use it in GitHub Desktop.
Make it easier to create templatetags with parameters.
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