On this page
Loop variable built-ins
Loop variable built-ins only exists since FreeMarker 2.3.23.
These built-ins you can only use with the loop variable of the list and items directives (and of the deprecated foreach directive). 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
This built-in is available since FreeMarker 2.3.23.
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
This built-in is available since FreeMarker 2.3.23.
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
This built-in is available since FreeMarker 2.3.23.
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
This built-in is available since FreeMarker 2.3.23.
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 or var?item_cycle(...) instead.
is_first
This built-in is available since FreeMarker 2.3.23.
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
This built-in is available since FreeMarker 2.3.23.
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
This built-in is available since FreeMarker 2.3.23.
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 or var?item_cycle(...) instead.
item_cycle
This built-in is available since FreeMarker 2.3.23.
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
This built-in is available since FreeMarker 2.3.23.
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 the item_cycle built-in to specify custom values, or more then two values.
item_parity_cap
This built-in is available since FreeMarker 2.3.23.
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".