5.3.7 <al-for>

This tag implements a loop in almost the same way as the for keyword in Python.

In the most simple form the expr attribute specifies an expression that yields a sequence and the iter attribute specifies the name of the sequence iterator. All of the enclosed content is then evaluated for each element in the sequence.

For example:

>>> import albatross
>>> ctx = albatross.SimpleContext('.')
>>> albatross.Template(ctx, '<magic>', '''
... <al-for iter="i" expr="range(15)" whitespace="indent">
...  <al-value expr="i.value()">
... </al-for whitespace>
... ''').to_html(ctx)
>>> ctx.flush_content()
 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

Any application that presents large lists of data will probably need to use pagination to limit the amount of data displayed on each page. The pagesize attribute places the sequence iterator into page mode and limits the number of elements that will be displayed.

For example:

>>> import albatross
>>> class Ctx(albatross.SimpleContext, albatross.HiddenFieldSessionMixin):
...     def __init__(self):
...         albatross.SimpleContext.__init__(self, '.')
... 
...
>>> ctx = Ctx()
>>> ctx.locals.__dict__.keys()
[]
>>> albatross.Template(ctx, '<magic>', '''
... <al-for iter="i" expr="range(500)" pagesize="20" whitespace="indent">
...  <al-value expr="i.value()">
... </al-for whitespace>
... ''').to_html(ctx)
>>> ctx.flush_content()
 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
>>> ctx.locals.__dict__.keys()
['i']

Pagination support requires that session support be present in the execution context. All of the Albatross application objects provide session capable execution contexts by default. The SimpleContext class does not support sessions so it is necessary to augment the class for the above example. Note also that when the <al-for> tag processes the pagesize attribute it places the sequence iterator into the session. The HiddenFieldSessionMixin class saves session state in hidden fields at the end of each <al-form> tag. Please refer to the ListIterator class documentation below.

Multiple pages from a sequence can be presented on the same page. By default the sequence index will reset to the first index displayed on the page. The continue attribute suppresses the sequence index reset causing the elements to flow on from the previous page.

For example:

>>> import albatross
>>> class Ctx(albatross.SimpleContext, albatross.HiddenFieldSessionMixin):
...     def __init__(self):
...         albatross.SimpleContext.__init__(self, '.')
...         albatross.HiddenFieldSessionMixin.__init__(self)
... 
>>> ctx = Ctx()
>>> albatross.Template(ctx, '<magic>', '''
... A:<al-for iter="i" expr="range(500)" pagesize="20" whitespace="indent">
...  <al-value expr="i.value()">
... </al-for whitespace>
... B:<al-for iter="i" pagesize="10" whitespace="indent">
...  <al-value expr="i.value()">
... </al-for whitespace>
... C:<al-for iter="i" pagesize="15" continue whitespace="indent">
...  <al-value expr="i.value()">
... </al-for whitespace>
... ''').to_html(ctx)
>>> ctx.flush_content()
A: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
B: 0 1 2 3 4 5 6 7 8 9
C: 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

Whenever you use pagination you must specify a pagesize attribute. It is important to note that if neither the pagesize nor the continue attributes are present a new iterator object is created.

When using all of the tag forms above you will only be able to place pagination controls after the formatted sequence content as the iterator is initialised when the expression in the expr attribute has been evaluated.

When the prepare attribute is present the <al-for> tag will perform all processing but will not write any output. This allows you to test pagination results before presenting output.

For example:

>>> import albatross
>>> class Ctx(albatross.SimpleContext, albatross.HiddenFieldSessionMixin):
...     def __init__(self):
...         albatross.SimpleContext.__init__(self, '.')
...         albatross.HiddenFieldSessionMixin.__init__(self)
... 
>>> ctx = Ctx()
>>> albatross.Template(ctx, '<magic>', '''
... <al-for iter="i" expr="range(500)" pagesize="20" prepare/>
... <al-if expr="i.has_prevpage()">prev</al-if>
... <al-for iter="i" pagesize="20" whitespace="indent">
...  <al-value expr="i.value()">
... </al-for>
... <al-if expr="i.has_nextpage()"> next</al-if whitespace>
... ''').to_html(ctx)
>>> ctx.flush_content()
 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 next

Note the XML empty tag syntax on the <al-for prepare> tag.

The <al-for> tag can also be used to format a sequence as multiple columns by specifying the cols and flow attributes. Multi-column formatting is only enabled when the cols attribute is present. The flow attribute can be either across or down. Default flow direction is down.

For example:

>>> import albatross
>>> ctx = albatross.SimpleContext('.')
>>> albatross.Template(ctx, '<magic>', '''
... <al-for iter="i" expr="range(15)" cols="4">
...  <al-for iter="c" expr="i.value()">
...   <al-value expr="' %2d' % c.value()">
...  </al-for whitespace>
... </al-for whitespace>
... <al-for iter="i" expr="range(15)" cols="4" flow="across">
...  <al-for iter="c" expr="i.value()">
...   <al-value expr="' %2d' % c.value()">
...  </al-for whitespace>
... </al-for>
... ''').to_html(ctx)
>>> ctx.flush_content()
  0  4  8 12
  1  5  9 13
  2  6 10 14
  3  7 11

  0  1  2  3
  4  5  6  7
  8  9 10 11
 12 13 14

The multi-column formatting does not currently support pagination.


Subsections