Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #3184 -- Changed the `unordered_list` template filter to use a …

…more simple format, while maintaining backwards compatibility with the old format. `unordered_list` now works with a simple list of items. Thanks for the patch, SmileyChris.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@6019 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 1a1a58c9f89f7b34fec05d426472b134d3e44096 1 parent 32c729b
Gary Wilson Jr. authored August 26, 2007
65  django/template/defaultfilters.py
@@ -355,8 +355,8 @@ def unordered_list(value):
355 355
     Recursively takes a self-nested list and returns an HTML unordered list --
356 356
     WITHOUT opening and closing <ul> tags.
357 357
 
358  
-    The list is assumed to be in the proper format. For example, if ``var`` contains
359  
-    ``['States', [['Kansas', [['Lawrence', []], ['Topeka', []]]], ['Illinois', []]]]``,
  358
+    The list is assumed to be in the proper format. For example, if ``var``
  359
+    contains: ``['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]``,
360 360
     then ``{{ var|unordered_list }}`` would return::
361 361
 
362 362
         <li>States
@@ -371,14 +371,61 @@ def unordered_list(value):
371 371
         </ul>
372 372
         </li>
373 373
     """
374  
-    def _helper(value, tabs):
  374
+    def convert_old_style_list(list_):
  375
+        """
  376
+        Converts old style lists to the new easier to understand format.
  377
+
  378
+        The old list format looked like:
  379
+            ['Item 1', [['Item 1.1', []], ['Item 1.2', []]]
  380
+
  381
+        And it is converted to:
  382
+            ['Item 1', ['Item 1.1', 'Item 1.2]]
  383
+        """
  384
+        if not isinstance(list_, (tuple, list)) or len(list_) != 2:
  385
+            return list_, False
  386
+        first_item, second_item = list_
  387
+        if second_item == []:
  388
+            return [first_item], True
  389
+        old_style_list = True
  390
+        new_second_item = []
  391
+        for sublist in second_item:
  392
+            item, old_style_list = convert_old_style_list(sublist)
  393
+            if not old_style_list:
  394
+                break
  395
+            new_second_item.extend(item)
  396
+        if old_style_list:
  397
+            second_item = new_second_item
  398
+        return [first_item, second_item], old_style_list
  399
+    def _helper(list_, tabs=1):
375 400
         indent = u'\t' * tabs
376  
-        if value[1]:
377  
-            return u'%s<li>%s\n%s<ul>\n%s\n%s</ul>\n%s</li>' % (indent, force_unicode(value[0]), indent,
378  
-                u'\n'.join([_helper(v, tabs+1) for v in value[1]]), indent, indent)
379  
-        else:
380  
-            return u'%s<li>%s</li>' % (indent, force_unicode(value[0]))
381  
-    return _helper(value, 1)
  401
+        output = []
  402
+
  403
+        list_length = len(list_)
  404
+        i = 0
  405
+        while i < list_length:
  406
+            title = list_[i]
  407
+            sublist = ''
  408
+            sublist_item = None
  409
+            if isinstance(title, (list, tuple)):
  410
+                sublist_item = title 
  411
+                title = ''
  412
+            elif i < list_length - 1:
  413
+                next_item = list_[i+1]
  414
+                if next_item and isinstance(next_item, (list, tuple)):
  415
+                    # The next item is a sub-list.
  416
+                    sublist_item = next_item
  417
+                    # We've processed the next item now too.
  418
+                    i += 1 
  419
+            if sublist_item:
  420
+                sublist = _helper(sublist_item, tabs+1)
  421
+                sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (indent, sublist,
  422
+                                                         indent, indent)
  423
+            output.append('%s<li>%s%s</li>' % (indent, force_unicode(title),
  424
+                                               sublist))
  425
+            i += 1
  426
+        return '\n'.join(output)
  427
+    value, converted = convert_old_style_list(value) 
  428
+    return _helper(value)
382 429
 
383 430
 ###################
384 431
 # INTEGERS        #
12  docs/templates.txt
@@ -1301,9 +1301,14 @@ unordered_list
1301 1301
 Recursively takes a self-nested list and returns an HTML unordered list --
1302 1302
 WITHOUT opening and closing <ul> tags.
1303 1303
 
  1304
+**Changed in Django development version**
  1305
+
  1306
+The format accepted by ``unordered_list`` has changed to an easier to
  1307
+understand format.
  1308
+
1304 1309
 The list is assumed to be in the proper format. For example, if ``var`` contains
1305  
-``['States', [['Kansas', [['Lawrence', []], ['Topeka', []]]], ['Illinois', []]]]``,
1306  
-then ``{{ var|unordered_list }}`` would return::
  1310
+``['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]``, then
  1311
+``{{ var|unordered_list }}`` would return::
1307 1312
 
1308 1313
     <li>States
1309 1314
     <ul>
@@ -1317,6 +1322,9 @@ then ``{{ var|unordered_list }}`` would return::
1317 1322
     </ul>
1318 1323
     </li>
1319 1324
 
  1325
+Note: the previous more restrictive and verbose format is still supported:
  1326
+``['States', [['Kansas', [['Lawrence', []], ['Topeka', []]]], ['Illinois', []]]]``,
  1327
+
1320 1328
 upper
1321 1329
 ~~~~~
1322 1330
 
19  tests/regressiontests/defaultfilters/tests.py
@@ -266,6 +266,22 @@
266 266
 >>> slice_(u'abcdefg', u'0::2')
267 267
 u'aceg'
268 268
 
  269
+>>> unordered_list([u'item 1', u'item 2'])
  270
+u'\t<li>item 1</li>\n\t<li>item 2</li>'
  271
+
  272
+>>> unordered_list([u'item 1', [u'item 1.1']])
  273
+u'\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t</ul>\n\t</li>'
  274
+
  275
+>>> unordered_list([u'item 1', [u'item 1.1', u'item1.2'], u'item 2'])
  276
+u'\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t\t<li>item1.2</li>\n\t</ul>\n\t</li>\n\t<li>item 2</li>'
  277
+
  278
+>>> unordered_list([u'item 1', [u'item 1.1', [u'item 1.1.1', [u'item 1.1.1.1']]]])
  279
+u'\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1\n\t\t<ul>\n\t\t\t<li>item 1.1.1\n\t\t\t<ul>\n\t\t\t\t<li>item 1.1.1.1</li>\n\t\t\t</ul>\n\t\t\t</li>\n\t\t</ul>\n\t\t</li>\n\t</ul>\n\t</li>'
  280
+
  281
+>>> unordered_list(['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']])
  282
+u'\t<li>States\n\t<ul>\n\t\t<li>Kansas\n\t\t<ul>\n\t\t\t<li>Lawrence</li>\n\t\t\t<li>Topeka</li>\n\t\t</ul>\n\t\t</li>\n\t\t<li>Illinois</li>\n\t</ul>\n\t</li>'
  283
+
  284
+# Old format for unordered lists should still work
269 285
 >>> unordered_list([u'item 1', []])
270 286
 u'\t<li>item 1</li>'
271 287
 
@@ -275,6 +291,9 @@
275 291
 >>> unordered_list([u'item 1', [[u'item 1.1', []], [u'item 1.2', []]]])
276 292
 u'\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t\t<li>item 1.2</li>\n\t</ul>\n\t</li>'
277 293
 
  294
+>>> unordered_list(['States', [['Kansas', [['Lawrence', []], ['Topeka', []]]], ['Illinois', []]]])
  295
+u'\t<li>States\n\t<ul>\n\t\t<li>Kansas\n\t\t<ul>\n\t\t\t<li>Lawrence</li>\n\t\t\t<li>Topeka</li>\n\t\t</ul>\n\t\t</li>\n\t\t<li>Illinois</li>\n\t</ul>\n\t</li>'
  296
+
278 297
 >>> add(u'1', u'2')
279 298
 3
280 299
 

0 notes on commit 1a1a58c

Please sign in to comment.
Something went wrong with that request. Please try again.