mirror of https://github.com/django/django.git
Fixed #23260: Added generator support to defaultfilters.unordered_list.
This commit is contained in:
parent
fe38be96c1
commit
b3660d28f3
|
@ -678,41 +678,44 @@ def unordered_list(value, autoescape=None):
|
||||||
second_item = new_second_item
|
second_item = new_second_item
|
||||||
return [first_item, second_item], old_style_list
|
return [first_item, second_item], old_style_list
|
||||||
|
|
||||||
def _helper(list_, tabs=1):
|
def walk_items(item_list):
|
||||||
|
item_iterator = iter(item_list)
|
||||||
|
for item in item_iterator:
|
||||||
|
try:
|
||||||
|
next_item = next(item_iterator)
|
||||||
|
except StopIteration:
|
||||||
|
next_item = None
|
||||||
|
if not isinstance(next_item, six.string_types):
|
||||||
|
try:
|
||||||
|
iter(next_item)
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
yield item, next_item
|
||||||
|
continue
|
||||||
|
yield item, None
|
||||||
|
if next_item:
|
||||||
|
yield next_item, None
|
||||||
|
|
||||||
|
def list_formatter(item_list, tabs=1):
|
||||||
indent = '\t' * tabs
|
indent = '\t' * tabs
|
||||||
output = []
|
output = []
|
||||||
|
for item, children in walk_items(item_list):
|
||||||
list_length = len(list_)
|
|
||||||
i = 0
|
|
||||||
while i < list_length:
|
|
||||||
title = list_[i]
|
|
||||||
sublist = ''
|
sublist = ''
|
||||||
sublist_item = None
|
if children:
|
||||||
if isinstance(title, (list, tuple)):
|
sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (
|
||||||
sublist_item = title
|
indent, list_formatter(children, tabs + 1), indent, indent)
|
||||||
title = ''
|
output.append('%s<li>%s%s</li>' % (
|
||||||
elif i < list_length - 1:
|
indent, escaper(force_text(item)), sublist))
|
||||||
next_item = list_[i + 1]
|
|
||||||
if next_item and isinstance(next_item, (list, tuple)):
|
|
||||||
# The next item is a sub-list.
|
|
||||||
sublist_item = next_item
|
|
||||||
# We've processed the next item now too.
|
|
||||||
i += 1
|
|
||||||
if sublist_item:
|
|
||||||
sublist = _helper(sublist_item, tabs + 1)
|
|
||||||
sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (indent, sublist,
|
|
||||||
indent, indent)
|
|
||||||
output.append('%s<li>%s%s</li>' % (indent,
|
|
||||||
escaper(force_text(title)), sublist))
|
|
||||||
i += 1
|
|
||||||
return '\n'.join(output)
|
return '\n'.join(output)
|
||||||
|
|
||||||
value, converted = convert_old_style_list(value)
|
value, converted = convert_old_style_list(value)
|
||||||
if converted:
|
if converted:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
"The old style syntax in `unordered_list` is deprecated and will "
|
"The old style syntax in `unordered_list` is deprecated and will "
|
||||||
"be removed in Django 2.0. Use the the new format instead.",
|
"be removed in Django 2.0. Use the the new format instead.",
|
||||||
RemovedInDjango20Warning)
|
RemovedInDjango20Warning)
|
||||||
return mark_safe(_helper(value))
|
return mark_safe(list_formatter(value))
|
||||||
|
|
||||||
|
|
||||||
###################
|
###################
|
||||||
|
|
|
@ -549,6 +549,12 @@ class DefaultFiltersTests(TestCase):
|
||||||
b = ULItem('b')
|
b = ULItem('b')
|
||||||
self.assertEqual(unordered_list([a, b]), '\t<li>ulitem-a</li>\n\t<li>ulitem-b</li>')
|
self.assertEqual(unordered_list([a, b]), '\t<li>ulitem-a</li>\n\t<li>ulitem-b</li>')
|
||||||
|
|
||||||
|
def item_generator():
|
||||||
|
yield a
|
||||||
|
yield b
|
||||||
|
|
||||||
|
self.assertEqual(unordered_list(item_generator()), '\t<li>ulitem-a</li>\n\t<li>ulitem-b</li>')
|
||||||
|
|
||||||
# Old format for unordered lists should still work
|
# Old format for unordered lists should still work
|
||||||
with warnings.catch_warnings(record=True):
|
with warnings.catch_warnings(record=True):
|
||||||
warnings.simplefilter("always")
|
warnings.simplefilter("always")
|
||||||
|
|
Loading…
Reference in New Issue