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"
.