Loop variable builtins
These built-ins you can only use with the loop variable of the list
and items
directives. Some explanation of that follows (loopVar?index
returns the 0-based index in the listable value we iterate through):
<#-- Note: x is a loop variable -->
<#list ['a', 'b', 'c'] as x>
${x?index}
</#list>
0
1
2
When the list
directive doesn’t specify the loop variable, these built-ins are used with the loop variable of the items directive:
<#list ['a', 'b', 'c']>
<ul>
<#items as x>
<li>${x?index}</li>
</#items>
</ul>
</#list>
Loop variable built-ins only use the name of loop variable, so that they can identify the related ongoing iteration. They don’t read the value of the loop variable. Hence, this is a parsing error:
<#list ['a', 'b', 'c'] as x>
<#assign y = x>
${y?index} <#-- ERROR: y isn't a loop variable -->
</#list>
counter
Returns the 1-based index where the iteration (which is identified by the loop variable name) currently stands.
<#list ['a', 'b', 'c'] as i>
${i?counter}: ${i}
</#list>
1: a
2: b
3: c
For the 0-based index, use the
index
built-in.
has_next
Tells if the item where the iteration (which is identified by the loop variable name) currently stands is not the last item.
<#list ['a', 'b', 'c'] as i>${i?has_next?c} </#list>
true true false
For separating items with commas and such, use
<#sep>separator</#sep>
instead of<#if var?has_next>separator</#if>
, as it’s more readable. (Furthermore the</#sep>
can be often omitted, like in<#list ... as var>...${var}...<#sep>separator</#list>
)
If you need the inverse of this built-in, use
var?is_last
instead of!var?has_next
, because it’s more readable.
index
Returns the 0-based index where the iteration (which is identified by the loop variable name) currently stands.
<#list ['a', 'b', 'c'] as i>
${i?index}: ${i}
</#list>
0: a
1: b
2: c
For the 1-based index, use the
counter
built-in.
is_even_item
Tells if the item where the iteration (which is identified by the loop variable name) currently stands has an even 1-based index.
<#list ['a', 'b', 'c', 'd'] as i>${i?is_even_item?c} </#list>
false true false true
To make tables with alternating row colors and such, use
var?item_parity
orvar?item_cycle(...)
instead.
is_first
Tells if the item where the iteration (which is identified by the loop variable name) currently stands is the first item.
<#list ['a', 'b', 'c'] as i>${i?is_first?c} </#list>
true false false
is_last
Tells if the item where the iteration (which is identified by the loop variable name) currently stands is the last item.
<#list ['a', 'b', 'c'] as i>${i?is_last?c} </#list>
false false true
If you need the inverse of this built-in, use
var?has_next
instead of!var?is_last
, because it’s more readable.
For separating items with commas and such, use
<#sep>separator</#sep>
instead of<#if var?has_next>separator</#if>
, as it’s more readable. (Furthermore the</#sep>
can be often omitted, like in<#list ... as var>...${var}...<#sep>separator</#list>
)
is_odd_item
Tells if the item where the iteration (which is identified by the loop variable name) currently stands has an odd 1-based index.
<#list ['a', 'b', 'c', 'd'] as i>${i?is_odd_item?c} </#list>
true false true false
To make tables with alternating row colors and such, use
var?item_parity
orvar?item_cycle(...)
instead.
item_cycle
This is a more generic version of the item_parity built-in, where you can specify what value to use instead of “odd” and “even”. It also allows more than 2 values that it will cycle through.
<#list ['a', 'b', 'c', 'd', 'e', 'f', 'g'] as i>
<tr class="${i?item_cycle('row1', 'row2', 'row3')}">${i}</tr>
</#list>
<tr class="row1">a</tr>
<tr class="row2">b</tr>
<tr class="row3">c</tr>
<tr class="row1">d</tr>
<tr class="row2">e</tr>
<tr class="row3">f</tr>
<tr class="row1">g</tr>
Some details:
-
The number of arguments must be at least 1, and has no upper limit.
-
The type of the arguments can be anything, they doesn’t have to be strings.
Use the
item_parity
built-in instead if the values you need are"odd"
and"even"
.
item_parity
Returns "odd"
or "even"
string value, depending on the parity of the 1-based index where the iteration (which is identified by the loop variable name) currently stands. This is commonly used for alternating color for table rows:
<#list ['a', 'b', 'c', 'd'] as i>
<tr class="${i?item_parity}Row">${i}</tr>
</#list>
<tr class="oddRow">a</tr>
<tr class="evenRow">b</tr>
<tr class="oddRow">c</tr>
<tr class="evenRow">d</tr>
Use the
item_parity_cap
built-in for capitalized"Odd"
and"Even"
. Use theitem_cycle
built-in to specify custom values, or more then two values.
item_parity_cap
Returns "Odd"
or "Even"
string value (note the capitalization), depending on the parity of the 1-based index where the iteration (which is identified by the loop variable name) currently stands.
<#list ['a', 'b', 'c', 'd'] as i>
<tr class="row${i?item_parity_cap}">${i}</tr>
</#list>
<tr class="rowOdd">a</tr>
<tr class="rowEven">b</tr>
<tr class="rowOdd">c</tr>
<tr class="rowEven">d</tr>
Use the
item_parity
built-in for lower case"odd"
and"even"
.