templates: additional forloop variable?

229 views
Skip to first unread message

Scott Moonen

unread,
Jul 13, 2008, 7:46:27 PM7/13/08
to django...@googlegroups.com
Within a Django template, sometimes I find myself wishing that I had access to the loop item from the previous iteration of a loop.

Usually the ifchanged tag is good enough for my purposes, but occasionally if some attribute of the loop item has changed I need to do further examination of the previous item to determine what sort of wrap-up (e.g., tag closing) needs to be done.

I'm considering adding a forloop.previous (or somesuch) variable to the supplemental variables produced by the for tag.  If forloop.first is true, this value would always be None, but otherwise it would reference the actual loop item from the prior iteration.

Is there sufficient interest in this that I should consider going the extra mile by opening a ticket and submitting a patch?  Or (please excuse my ignorance!) is opening a ticket actually the preferred way to gauge the interest level?

  -- Scott

--
http://scott.andstuff.org/ | http://truthadorned.org/

Tim Chase

unread,
Jul 13, 2008, 8:05:47 PM7/13/08
to django...@googlegroups.com
> I'm considering adding a forloop.previous (or somesuch)
> variable to the supplemental variables produced by the for
> tag. If forloop.first is true, this value would always be
> None, but otherwise it would reference the actual loop item
> from the prior iteration.


I'd be tempted to do it as a filter...something like

def look_behind(iterable, default):
prev = default
while True:
next = iterable.next()
yield prev, next
prev = next

def look_ahead(iterable, default):
i = iter(iterable)
a = b = default
try:
a = i.next()
while True:
b = i.next()
yield a, b
a = b
except StopIteration:
yield a, default

which, after registering them as filters (adjusting as desired),
you can use them like

{% for cur, next in things|look_ahead %}
doing something with {{ cur }} and {{ next }}
{% endfor %}

or similarly looking backwards:

{% for prev, cur in things|look_ahead:"FIRST" %}
doing something with {{ prev }} and {{ cur }}
{% endfor %}

-tim


Russell Keith-Magee

unread,
Jul 14, 2008, 7:53:31 AM7/14/08
to django...@googlegroups.com
On Mon, Jul 14, 2008 at 7:46 AM, Scott Moonen <smo...@andstuff.org> wrote:
> I'm considering adding a forloop.previous (or somesuch) variable to the
> supplemental variables produced by the for tag. If forloop.first is true,
> this value would always be None, but otherwise it would reference the actual
> loop item from the prior iteration.

I can't help but get the feeling that there is another way to skin
your cat. However, without knowing exactly what you're trying to do,
its difficult to tell for certain.

> Is there sufficient interest in this that I should consider going the extra
> mile by opening a ticket and submitting a patch?

I can't vouch for the community as a whole, but as fair warning: the
core developers are preoccupied with delivering v1.0 at the moment, so
you may find that suggestions about improvements that aren't on the
schedule for v1.0 will probably get ignored for a little while

> Or (please excuse my
> ignorance!) is opening a ticket actually the preferred way to gauge the
> interest level?

Generally, doing both is a good idea. The ticket tracks the idea
itself - if nobody is interested, we can close the ticket, and if
anyone else has the same idea later on, we can point them at the
ticket. The mailing list enables you to establish who is interested in
the idea, and nail down the little details.

Yours,
Russ Magee %-)

Scott Moonen

unread,
Jul 14, 2008, 8:19:32 AM7/14/08
to django...@googlegroups.com
(Tim - thanks for the suggestion.)

Russ,


I'm considering adding a forloop.previous (or somesuch) variable to the
supplemental variables produced by the for tag.  If forloop.first is true,
this value would always be None, but otherwise it would reference the actual
loop item from the prior iteration.

I can't help but get the feeling that there is another way to skin
your cat. However, without knowing exactly what you're trying to do,
its difficult to tell for certain.

Here's my use case: think tags with tag bundles.  So I have a list of tags for an object that are like ("AGroup:Tag1", "AGroup:Tag2", "FluxCapacitor", "ZGroup:Tag1", "ZGroup:Tag2").  At the moment I'm storing tags like this, as "bundle:tagname" or "tagname".  For display purposes I order them by that string, and format bundles within a <dl>, but individual tags as-is.  When <% ifchanged tag.get_bundle %> (get_bundle is an instance method), I want to determine whether I need to emit a </dl>, so I need to access the previous tag in the list to determine if get_bundle returns an empty string.

As I write this, "forloop.previous" aside, it occurs to me that an alternate approach might be for me to provide the unbundled and bundled tags to my template in separate lists and display the unbundled tags all together rather than interspersed.  Come to think of it, that might actually display more attractively -- it could be rather ugly to have tags and bundles interspersed.

Thank you for serving as my CardboardProgrammer for the day. :)

  -- Scott
Reply all
Reply to author
Forward
0 new messages