Up to now, templates must "know" subpanels and parameters by name to use them. This isn't a problem in most circumstances. However, a template might want to render a menu tree, where items are passed through by the panel definition; or, it might want to layout news items in a column, where the blocks of content are defined by a list of subpanels.

To satisfy these needs, <panel> elements may contain <list> elements as children. A <list> element requires a name attribute. As with subpanels and parameters, the name attribute values must be unique under the <panel>'s <list> children.

A list contains a sequence of <item> elements. An <item> element contains a mixed sequence of <panel>, <param> and - you guessed it - <list> elements.

A template uses the <list> tag to iterate over a list contained in the current panel. During iteration, the current item behaves as if its children elements were moved up to the current panel. That is - semantically - the current item is merged with the current panel.

As an example, consider the following panel definition:

<panel name="/blurb" template="/jsp/column.jsp">
  <list name="blurbs">
      <param name="head" value="Item 1"/>
      <panel name="body" template="/jsp/blurb1.jsp"/>
      <param name="head" value="Item 2"/>
      <panel name="body" template="/jsp/blurb2.jsp"/>
      <param name="head" value="Item 3"/>
      <panel name="body" template="/jsp/blurb3.jsp"/>

The <panels:list> element also accepts an optional varStatus attribute. If set, the tag will export a list status object to that attribute in page scope. The list status object provides methods boolean isFirst(), boolean isLast() and int getIndex(), which may be used to retrieve information about the position of the current item within the list.