The {% switch %}
tag compares a variable against one or more values in
{% case %}
tags, and outputs the contents of the matching block. An
optional {% else %}
tag sets off the default output if no matches
could be found:
{% switch result_count %}
{% case 0 %}
There are no search results.
{% case 1 %}
There is one search result.
{% else %}
Jackpot! Your search found {{ result_count }} results.
{% endswitch %}
Each {% case %}
tag can take multiple values to compare the variable
against:
{% switch username %}
{% case "Jim" "Bob" "Joe" %}
Me old mate {{ username }}! How ya doin?
{% else %}
Hello {{ username }}
{% endswitch %}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | from django import template
from django.template import Library, Node, VariableDoesNotExist
register = Library()
@register.tag(name="switch")
def do_switch(parser, token):
"""
The ``{% switch %}`` tag compares a variable against one or more values in
``{% case %}`` tags, and outputs the contents of the matching block. An
optional ``{% else %}`` tag sets off the default output if no matches
could be found::
{% switch result_count %}
{% case 0 %}
There are no search results.
{% case 1 %}
There is one search result.
{% else %}
Jackpot! Your search found {{ result_count }} results.
{% endswitch %}
Each ``{% case %}`` tag can take multiple values to compare the variable
against::
{% switch username %}
{% case "Jim" "Bob" "Joe" %}
Me old mate {{ username }}! How ya doin?
{% else %}
Hello {{ username }}
{% endswitch %}
"""
bits = token.contents.split()
tag_name = bits[0]
if len(bits) != 2:
raise template.TemplateSyntaxError("'%s' tag requires one argument" % tag_name)
variable = parser.compile_filter(bits[1])
class BlockTagList(object):
# This is a bit of a hack, as it embeds knowledge of the behaviour
# of Parser.parse() relating to the "parse_until" argument.
def __init__(self, *names):
self.names = set(names)
def __contains__(self, token_contents):
name = token_contents.split()[0]
return name in self.names
# Skip over everything before the first {% case %} tag
parser.parse(BlockTagList('case', 'endswitch'))
cases = []
token = parser.next_token()
got_case = False
got_else = False
while token.contents != 'endswitch':
nodelist = parser.parse(BlockTagList('case', 'else', 'endswitch'))
if got_else:
raise template.TemplateSyntaxError("'else' must be last tag in '%s'." % tag_name)
contents = token.contents.split()
token_name, token_args = contents[0], contents[1:]
if token_name == 'case':
tests = map(parser.compile_filter, token_args)
case = (tests, nodelist)
got_case = True
else:
# The {% else %} tag
case = (None, nodelist)
got_else = True
cases.append(case)
token = parser.next_token()
if not got_case:
raise template.TemplateSyntaxError("'%s' must have at least one 'case'." % tag_name)
return SwitchNode(variable, cases)
class SwitchNode(Node):
def __init__(self, variable, cases):
self.variable = variable
self.cases = cases
def __repr__(self):
return "<Switch node>"
def __iter__(self):
for tests, nodelist in self.cases:
for node in nodelist:
yield node
def get_nodes_by_type(self, nodetype):
nodes = []
if isinstance(self, nodetype):
nodes.append(self)
for tests, nodelist in self.cases:
nodes.extend(nodelist.get_nodes_by_type(nodetype))
return nodes
def render(self, context):
try:
value_missing = False
value = self.variable.resolve(context, True)
except VariableDoesNotExist:
no_value = True
value_missing = None
for tests, nodelist in self.cases:
if tests is None:
return nodelist.render(context)
elif not value_missing:
for test in tests:
test_value = test.resolve(context, True)
if value == test_value:
return nodelist.render(context)
else:
return ""
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
- Help text hyperlinks by sa2812 1 year, 8 months ago
Comments
Please login first before commenting.