Thanks for your reply, I really like the general iterator approach.
This recipe will definitely go to my personal "standard" library.

A.

On Dec 2, 11:09 pm, Tim Chase <[EMAIL PROTECTED]> wrote:
> > If your data is in the 'data' context variable, then try this:
>
> >         <table>
> >         {% for d in data %}
> >             {% if forloop.counter0|divisibleby:"2" %}<tr>{% endif %}
> >             <td>{{d}}</td>
> >             {% if forloop.counter|divisibleby:"2" %}</tr>{% endif %}
> >         {% endfor %}
> >         {% if data|length|divisibleby:"2" %}{% else
> > %}<td>&nbsp;</td></tr>{% endif %}
> >         </table>
>
> > It's a little awkward, and doesn't generalize to more than two columns,
> > but it does produce properly structured HTML.
>
> It can be generalized, as I've done it in a pinch, and it looks
> something like this (untested, as I don't have my actual code
> right in front of me):
>
> <table>
>   <tr>
> {% for d in data %}
>    <td>{{d}}</td>
>   {% if forloop.counter|divisibleby:"4" %}</tr><tr>{% endif %}
> {% endfor %}
>   </tr>
> </table>
>
> HTML is forgiving if you don't have the right number of columns
> in your final row (don't know about XHTML's definition).  And it
> adds a bogus row at the bottom if your dataset is divisible by N.
>
> A better way would be to make a custom template filter that
> breaks the data-set into groups.
>
> #####################################
> from itertools import izip, islice
>
> def pad(iterable, length, padding=None):
>   i = 0
>   for thing in iterable:
>     i += 1
>     yield thing
>   for i in xrange(length - i):
>     yield padding
>
> def columnize(dataset, args="2"):
>   if "," in str(args):
>         columns, padding = args.split(",",1)
>   else:
>         columns = args
>         padding = ""
>   columns = int(columns)
>   row_count, leftovers = divmod(len(dataset), columns)
>   if leftovers: row_count += 1
>   return izip(*(
>     pad(islice(dataset, i, None, columns), row_count, padding)
>     for i in xrange(columns)
>     ))
> #####################################
>
> and then register columnize your filter.  It should presume 2
> columns, but be extensible to more than two columns with an
> optional parameter.  It also takes optional padding as a
> parameter, so it can be called like
>
>  <table>
>  {% for thing in data|columnize:"3,&nbsp;" %}
>    <tr>
>     {% for value in thing %}
>      <td>{{ value }}</td>
>     {% endfor %}
>    </tr>
>  {% endfor %}
>  </table>
>
> or
>
>  <table>
>  {% for thing in my_queryset|columnize %}
>    <tr>
>     {% for value in thing %}
>      <td>
>       {% if value %}
>         <b>{{ value.name }}:</b>
>         {{ value.other_field }}
>       {% else %}
>         &nbsp;
>       {% endif %}
>      </td>
>     {% endfor %}
>    </tr>
>  {% endfor %}
>  </table>
>
> which is about as clean a solution as it gets, as it guarantees
> "square" result-sets that have been padded out.
>
> -tim
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to