From c5e5c0fc3573f050d2db08517f88db2e16379455 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Fri, 25 Nov 2005 00:54:40 +0000 Subject: [PATCH] Fixed #625 -- Added template-tag decorators simple_tag and inclusion_tag. Taken from new-admin. Thanks, rjwittams git-svn-id: http://code.djangoproject.com/svn/django/trunk@1410 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/core/template/decorators.py | 67 ++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 django/core/template/decorators.py diff --git a/django/core/template/decorators.py b/django/core/template/decorators.py new file mode 100644 index 0000000000..2a61a600ec --- /dev/null +++ b/django/core/template/decorators.py @@ -0,0 +1,67 @@ +from django.core.template import Context, Node, TemplateSyntaxError, register_tag, resolve_variable +from django.core.template_loader import get_template +from django.utils.functional import curry +from inspect import getargspec + +def generic_tag_compiler(params, defaults, name, node_class, parser, token): + "Returns a template.Node subclass." + bits = token.contents.split()[1:] + bmax = len(params) + def_len = defaults and len(defaults) or 0 + bmin = bmax - def_len + if(len(bits) < bmin or len(bits) > bmax): + if bmin == bmax: + message = "%s takes %s arguments" % (name, bmin) + else: + message = "%s takes between %s and %s arguments" % (name, bmin, bmax) + raise TemplateSyntaxError, message + return node_class(bits) + +def simple_tag(func): + (params, xx, xxx, defaults) = getargspec(func) + + class SimpleNode(Node): + def __init__(self, vars_to_resolve): + self.vars_to_resolve = vars_to_resolve + + def render(self, context): + resolved_vars = [resolve_variable(var, context) for var in self.vars_to_resolve] + return func(*resolved_vars) + + compile_func = curry(generic_tag_compiler, params, defaults, func.__name__, SimpleNode) + compile_func.__doc__ = func.__doc__ + register_tag(func.__name__, compile_func) + return func + +def inclusion_tag(file_name, context_class=Context, takes_context=False): + def dec(func): + (params, xx, xxx, defaults) = getargspec(func) + if takes_context: + if params[0] == 'context': + params = params[1:] + else: + raise TemplateSyntaxError, "Any tag function decorated with takes_context=True must have a first argument of 'context'" + + class InclusionNode(Node): + def __init__(self, vars_to_resolve): + self.vars_to_resolve = vars_to_resolve + + def render(self, context): + resolved_vars = [resolve_variable(var, context) for var in self.vars_to_resolve] + if takes_context: + args = [context] + resolved_vars + else: + args = resolved_vars + + dict = func(*args) + + if not getattr(self, 'nodelist', False): + t = get_template(file_name) + self.nodelist = t.nodelist + return self.nodelist.render(context_class(dict)) + + compile_func = curry(generic_tag_compiler, params, defaults, func.__name__, InclusionNode) + compile_func.__doc__ = func.__doc__ + register_tag(func.__name__, compile_func) + return func + return dec