Foreachelse
{foreach}, {foreachelse}The {foreach} tag is used to create simple loops.
- from: the array that you want to iterate over
- key: variable name for the key (or for the item if item is not defined)
- item: variable name for each item
- name: foreach name to access it’s iterator variables
- implode: if provided, this will be added between every item
{foreach}loops can be nested.- The
arrayvariable, usually an array of values, determines the number of times{foreach}will loop. You can also pass an integer for arbitrary loops. -
{foreachelse} or {else}is executed when there are no values in thearrayvariable. -
{foreach}properties are@index,@iteration,@first,@last,@show,@total. -
Instead of specifying the
keyvariable you can access the current key of the loop item by{$item@key}(see examples below).
$arr = [
['id'=>1, 'name'=>'Jim'],
['id'=>2, 'name'=>'John'],
['id'=>3, 'name'=>'Bob'],
];
{foreach $arr val implode=", "}
{$val.id} - {$val.name}
{/foreach}
OR
{foreach from=$arr item=val }
{$val.id} - {$val.name}
{/foreach}
Output
1 - Jim,
2 - John,
3 - Bob
@index contains the current array index, starting with zero.
{foreach $contacts as contact}
//For index value display
{$contact@index}
//For condition
{if $contact@index == 1}OK{else}No{/if}
{/foreach}
@iteration contains the current loop iteration and always starts at one, unlike index. It is incremented by one on each iteration.
The "is div by" operator can be used to detect a specific iteration. Here we bold-face the name every 4th iteration.
{foreach $contacts as contact}
{* For iteration value display *}
{$contacts@iteration}
{* For condition *}
{if $contact@iteration is div by 4}OK{else}No{/if}
{/foreach}
The "is even by" and "is odd by" operators can be used to alternate something every so many iterations. Choosing between even or odd rotates which one starts. Here we switch the font color every 3rd iteration.
{foreach $myNames as name}
{if $name@index is even by 3}
{$name}
{else}
{$name}
{/if}
{/foreach}
@first first is TRUE if the current {foreach} iteration is the initial one. Here we display a table header row on the first iteration.
{* show table header at first iteration *}
<table>
{foreach $items as row}
{if $row@first}
<tr>
<th>key</td>
<th>name</td>
</tr>
{/if}
<tr>
<td>{$row@key}</td>
<td>{$row.name}</td>
</tr>
{/foreach}
</table>
@last is set to TRUE if the current {foreach} iteration is the final one. Here we display a horizontal rule on the last iteration.
{* Add horizontal rule at end of list *}
{foreach $items as item}
<a href="#{$item.id}">{$item.name}</a>{if $item@last}<hr>{else},{/if}
{foreachelse}
... no items to loop ...
{/foreach}
@show The show show property can be used after the execution of a {foreach} loop to detect if data has been displayed or not. show is a boolean value.
<ul>
{foreach $myArray as name}
<li>{$name}</li>
{/foreach}
</ul>
{if $@show} do something here if the array contained data {/if}
@total total contains the number of iterations that this {foreach} will loop. This can be used inside or after the {foreach}.
{* show number of rows at end *}
{foreach $items as item}
{$item.name}<hr/>
{if $item@last}
<div id="total">{$item@total} items</div>
{/if}
{foreachelse}
... no items to loop ...
{/foreach}
- The implode parameter allows you to use a comma or whatever you want to use to separate your items in a much easier way than having to do
{if $.foreach.name.last},{/if}inside the foreach block for example.