Login

Template tag: split list to n sublists

Author:
movielady
Posted:
July 16, 2008
Language:
HTML/template
Version:
Not specified
Score:
3 (after 3 ratings)

Based on this snippet, adapted to split a list into n number of sublists, e.g. split a list of results into three evenly-divided sublists to enable display of the results in three columns on one page with CSS.

Tag: {% list_to_columns your_list as new_list number_of_columns %}

The split_seq solution comes from a comment by Sebastian Hempel on this post.

More info here.

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

class SplitListNode(Node):
    def __init__(self, list, cols, new_list):
        self.list, self.cols, self.new_list = list, cols, new_list

    def split_seq(self, list, cols=2):
        start = 0 
        for i in xrange(cols): 
            stop = start + len(list[i::cols]) 
            yield list[start:stop] 
            start = stop

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

def list_to_columns(parser, token):
    """Parse template tag: {% list_to_columns list as new_list 2 %}"""
    bits = token.contents.split()
    if len(bits) != 5:
        raise TemplateSyntaxError, "list_to_columns list as new_list 2"
    if bits[2] != 'as':
        raise TemplateSyntaxError, "second argument to the list_to_columns tag must be 'as'"
    return SplitListNode(bits[1], bits[4], bits[3])
    
list_to_columns = register.tag(list_to_columns)

More like this

  1. Bootstrap Accordian by Netplay4 7 years, 9 months ago
  2. Bootstrap theme for django-endless-pagination? by se210 10 years, 9 months ago
  3. Bootstrap theme for django-endless-pagination? by se210 10 years, 9 months ago
  4. Reusable form template with generic view by roldandvg 10 years, 10 months ago
  5. Pagination Django with Boostrap by guilegarcia 11 years ago

Comments

movielady (on July 16, 2008):

Example usage:

{% load list_to_columns %}
{% list_to_columns people as list 3 %}
    {% for l in list %}
        (cycle through your div and ul code)
            {%for p in l %}
                (cycle through your list items)
            {% endfor %}
        (end ul and div tags)
    {% endfor %}

#

kjellmf (on September 30, 2008):

This snippet is really useful. Thanks for sharing.

One word of warning. If you pass a queryset to list_to_columns, a large number of SQL queries will be executed. To reduce the number of queries to one you could force the evaluation of the queryset prior to splitting the list:

def split_seq(self, list, cols=2):
    start = 0
    tmplist=tuple(list)  
    for i in xrange(cols): 
        stop = start + len(tmplist[i::cols]) 
        yield list[start:stop] 
        start = stop

Not sure if this is the best approach, but it reduces the number of queries.

#

gregb (on August 26, 2009):

Also, try using

from django.template import Library, Node, Variable
...
    def render(self, context):
        list = Variable(self.list).resolve(context)
        context[self.new_list] = self.split_seq(list, int(self.cols))
        return ''

in order to utilise django's variable parsing ability. (Your solution fails if you're trying to split a sub-variable, for eg

{% list_to_columns page.object_list as columns 2 %}

#

Please login first before commenting.