Login

TemplateTag to Split a List into Uniform Chunks

Author:
cmcavoy
Posted:
March 23, 2008
Language:
Python
Version:
.96
Score:
5 (after 5 ratings)

Creates a template tag called "split_list" which can split a list into chunks of a given size. For instance, if you have a list 'some_data', and you want to put it into a table with three items per row, you could use this tag:

{% split_list some_data as chunked_data 3 %}

Given a some_data of [1,2,3,4,5,6], the context variable 'chunked_data' becomes [[1,2,3],[4,5,6]]

This is useful for creating rows of equal numbers of items.

Thanks to the users of #django (pauladamsmith, Adam_G, and ubernostrum) for advice and pointers, thanks to Guyon Morée for writing the chunking recipe that this tag is based on.

 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
from django.template import Library, Node
     
register = Library()

class SplitListNode(Node):
    def __init__(self, list_string, chunk_size, new_list_name):
        self.list = list_string
        self.chunk_size = chunk_size
        self.new_list_name = new_list_name

    def split_seq(self, seq, size):
        """ Split up seq in pieces of size, from
        http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/425044"""
        return [seq[i:i+size] for i in range(0, len(seq), size)]

    def render(self, context):
        context[self.new_list_name] = self.split_seq(context[self.list], int(self.chunk_size))
        return ''

def split_list(parser, token):
    """<% split_list list as new_list 5 %>"""
    bits = token.contents.split()
    if len(bits) != 5:
        raise TemplateSyntaxError, "split_list list as new_list 5"
    return SplitListNode(bits[1], bits[4], bits[3])
    
split_list = register.tag(split_list)

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

noufal (on August 2, 2010):

Useful but if I say something like

{% list_to_columns obj.list_item as lists 2 %}

it borks because while obj is there in the context, obj.list_item is not. I used a dirty trick to work around this. Perhaps it's useful to you as well

def render(self, context):
    if "." in self.list:
        obj, attrs = self.list.split(".",1)
        obj = context[obj]
        attrs = attrs.split(".")
        for i in attrs:
            obj = getattr(obj,i)
        self.list = obj
    else:
        self.list = context[self.list]
    context[self.new_list] = self.split_seq(self.list, int(self.cols))
    return ''

#

Please login first before commenting.