From 4aa97f5c18f1242d4ef33931cf7567f997f24a6f Mon Sep 17 00:00:00 2001 From: Jacob Kaplan-Moss Date: Mon, 24 Nov 2008 22:01:48 +0000 Subject: [PATCH] Fixed #6398: added an optional `{% empty %}` clause to the `{% for %}` template tag. The contents of this clause are rendered if the list iterated over turns out to be empty. Thanks, Jannis Leidel. Astute readers will notice that the patch originally called this `default`; after consideration I decided that `empty` is a very slightly better color for this particular bikeshed. git-svn-id: http://code.djangoproject.com/svn/django/trunk@9530 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/template/defaulttags.py | 48 +++++++++++++++++++++--- docs/ref/templates/builtins.txt | 29 ++++++++++++++ tests/regressiontests/templates/tests.py | 3 ++ 3 files changed, 75 insertions(+), 5 deletions(-) diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py index 8182cd4d8c..06ad5c635a 100644 --- a/django/template/defaulttags.py +++ b/django/template/defaulttags.py @@ -83,10 +83,14 @@ class FirstOfNode(Node): return u'' class ForNode(Node): - def __init__(self, loopvars, sequence, is_reversed, nodelist_loop): + def __init__(self, loopvars, sequence, is_reversed, nodelist_loop, nodelist_empty=None): self.loopvars, self.sequence = loopvars, sequence self.is_reversed = is_reversed self.nodelist_loop = nodelist_loop + if nodelist_empty is None: + self.nodelist_empty = NodeList() + else: + self.nodelist_empty = nodelist_empty def __repr__(self): reversed_text = self.is_reversed and ' reversed' or '' @@ -97,16 +101,18 @@ class ForNode(Node): def __iter__(self): for node in self.nodelist_loop: yield node + for node in self.nodelist_empty: + yield node def get_nodes_by_type(self, nodetype): nodes = [] if isinstance(self, nodetype): nodes.append(self) nodes.extend(self.nodelist_loop.get_nodes_by_type(nodetype)) + nodes.extend(self.nodelist_empty.get_nodes_by_type(nodetype)) return nodes def render(self, context): - nodelist = NodeList() if 'forloop' in context: parentloop = context['forloop'] else: @@ -121,6 +127,9 @@ class ForNode(Node): if not hasattr(values, '__len__'): values = list(values) len_values = len(values) + if len_values < 1: + return self.nodelist_empty.render(context) + nodelist = NodeList() if self.is_reversed: values = reversed(values) unpack = len(self.loopvars) > 1 @@ -610,6 +619,30 @@ def do_for(parser, token): {{ key }}: {{ value }} {% endfor %} + The ``for`` tag can take an optional ``{% empty %}`` clause that will + be displayed if the given array is empty or could not be found:: + +