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