diff options
| author | Adrian Holovaty <adrian@holovaty.com> | 2005-11-25 00:54:40 +0000 |
|---|---|---|
| committer | Adrian Holovaty <adrian@holovaty.com> | 2005-11-25 00:54:40 +0000 |
| commit | c5e5c0fc3573f050d2db08517f88db2e16379455 (patch) | |
| tree | 42a78347a01e10ea8982075e1e62773ae0900f37 | |
| parent | 84eb80bbd79af35293797fd77766513b28c8a7da (diff) | |
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
| -rw-r--r-- | django/core/template/decorators.py | 67 |
1 files changed, 67 insertions, 0 deletions
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 |
