Browse Source

Batch template filter

Rafał Pitoń 11 years ago
parent
commit
2a5f49113d

+ 23 - 1
docs/developers/template_tags.rst

@@ -6,7 +6,7 @@ Misago defines plenty of custom tags and filters for use by template authors.
 
 
 
 
 misago_avatars
 misago_avatars
-=============
+==============
 
 
 ``avatar`` filter
 ``avatar`` filter
 -----------------
 -----------------
@@ -24,6 +24,28 @@ Returns link to avatar blank avatar that can be used as ``src`` attribute value
 Takes one optional argument, image size.
 Takes one optional argument, image size.
 
 
 
 
+misago_batch
+============
+
+There are situations when you want to slice list of items in template into sublists, e.g. when displaying grid of items in HTML it makes more sense to split iteration into two steps: iteration over rows and items in each row.
+
+``misago_batch`` provides two simple and lazy filters that enable you to do this:
+
+
+``batch`` filter
+----------------
+
+Takes one argument, integer individual batch length, then turns big list into list of lists.
+
+
+``batchnonefilled`` filter
+----------------
+
+Works same as ``batch`` filter, but with one difference:
+
+If last batch length is shorter than requested, it fills it with ``None`` to make it requested length.
+
+
 misago_capture
 misago_capture
 ==============
 ==============
 
 

+ 41 - 0
misago/core/templatetags/misago_batch.py

@@ -0,0 +1,41 @@
+from django import template
+from django.template import Context
+
+
+register = template.Library()
+
+
+@register.filter
+def batch(items, size):
+    batch_size = 0
+    batch_items = []
+
+    for item in items:
+        batch_size += 1
+        batch_items.append(item)
+
+        if batch_size == size:
+            yield batch_items
+            batch_size = 0
+            batch_items = []
+
+    yield batch_items
+
+
+@register.filter
+def batchnonefilled(items, size):
+    batch_size = 0
+    batch_items = []
+
+    for item in items:
+        batch_size += 1
+        batch_items.append(item)
+
+        if batch_size == size:
+            yield batch_items
+            batch_size = 0
+            batch_items = []
+
+    if batch_size:
+        batch_items.extend([None] * (size - batch_size))
+    yield batch_items

+ 31 - 0
misago/core/tests/test_templatetags.py

@@ -1,6 +1,8 @@
 from django.template import Context, Template, TemplateSyntaxError
 from django.template import Context, Template, TemplateSyntaxError
 from django.test import TestCase
 from django.test import TestCase
+
 from misago.core import forms
 from misago.core import forms
+from misago.core.templatetags import misago_batch
 
 
 
 
 class CaptureTests(TestCase):
 class CaptureTests(TestCase):
@@ -39,6 +41,35 @@ Hello, <b>{{ the_var|safe }}</b>
         self.assertIn('<b>The&lt;hr&gt;Html</b>', render)
         self.assertIn('<b>The&lt;hr&gt;Html</b>', render)
 
 
 
 
+class BatchTests(TestCase):
+    def test_batch(self):
+        """standard batch yields valid results"""
+        batch = 'loremipsum'
+        yields = (
+            ['l', 'o', 'r'],
+            ['e', 'm', 'i'],
+            ['p', 's', 'u'],
+            ['m',],
+        )
+
+        for i, test_yield in enumerate(misago_batch.batch(batch, 3)):
+            self.assertEqual(test_yield, yields[i])
+
+    def test_batchnonefilled(self):
+        """none-filled batch yields valid results"""
+        batch = 'loremipsum'
+        yields = (
+            ['l', 'o', 'r'],
+            ['e', 'm', 'i'],
+            ['p', 's', 'u'],
+            ['m', None, None],
+        )
+
+        for i, test_yield in enumerate(misago_batch.batchnonefilled(batch, 3)):
+            self.assertEqual(test_yield, yields[i])
+
+
+
 class TestForm(forms.Form):
 class TestForm(forms.Form):
     somefield = forms.CharField(label="Hello!", max_length=255)
     somefield = forms.CharField(label="Hello!", max_length=255)