Last active
December 27, 2015 18:39
-
-
Save gdugas/7371737 to your computer and use it in GitHub Desktop.
Django include tag: include_selected
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 | |
from django.template import Context, loader | |
from django.template.base import Node, token_kwargs, TemplateSyntaxError | |
from django.utils import six | |
from django.conf import settings | |
register = template.Library() | |
class IncludeSelectedNode(Node): | |
def __init__(self, templates, extra_context={}, options={}): | |
self.templates = templates | |
self.extra_context = extra_context | |
self.options = options | |
options.setdefault('only', False) | |
options.setdefault('once', False) | |
def render(self, context): | |
inc_stack = getattr(context, 'inc_stack', []) | |
templates = [t.resolve(context) for t in self.templates] | |
extra_context = {key: value.resolve(context) for key, value in six.iteritems(self.extra_context)} | |
try: | |
t = loader.select_template(templates) | |
if self.options['once'] and t.name in inc_stack: | |
return '' | |
inc_stack.append(t.name) | |
setattr(context, 'inc_stack', inc_stack) | |
c = Context() | |
if not self.options['only']: | |
c.update(context) | |
c.update(extra_context) | |
return t.render(c) | |
except: | |
if settings.TEMPLATE_DEBUG: | |
raise | |
return '' | |
@register.tag | |
def include_selected(parser, token): | |
flags = ['only', 'once'] | |
splitted = token.split_contents() | |
# tag name poping | |
splitted.pop(0) | |
templates = [] | |
while len(splitted) > 0 and not splitted[0] == 'with' and not splitted[0] in flags: | |
templates.append(parser.compile_filter(splitted.pop(0))) | |
extra_context = {} | |
if len(splitted) > 0 and splitted[0] == 'with': | |
splitted.pop(0) | |
while len(splitted) > 0 and not splitted[0] in flags: | |
extra_context = token_kwargs(splitted, parser) | |
options = {} | |
while len(splitted) > 0: | |
flag = splitted.pop() | |
if not flag in flags: | |
raise TemplateSyntaxError("Unknown parameter: %s" % flag) | |
options[flag] = True | |
return IncludeSelectedNode(templates, extra_context=extra_context, options=options) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here is a django template tags which allow you to specify multiple templates in case of the firsts does not exists
Syntax
with and only
Like include template tag, you can pass additional context to the template and render the context only with the variables provided:
once
You can also pass the once parameter, which will only include once time the selected template for the current context: