PageRenderTime 3ms CodeModel.GetById 2ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/documentation/en/designers/language-builtin-functions/language-function-foreach.xml

https://bitbucket.org/hallgrennetworks/smarty
XML | 531 lines | 470 code | 40 blank | 21 comment | 0 complexity | 0c19ad488b692b124b85684ab6527263 MD5 | raw file
  1<?xml version="1.0" encoding="UTF-8"?>
  2<!-- $Revision$ -->
  3<sect1 id="language.function.foreach">
  4 <title>{foreach},{foreachelse}</title> 
  5 <para>
  6  <varname>{foreach}</varname> is used for looping over arrays of data. <varname>{foreach}</varname> has a simpler and cleaner syntax than the <link linkend="language.function.section"><varname>{section}</varname></link> loop, and can also loop over associative arrays.
  7 </para>
  8 <para>
  9  <varname>{foreach $arrayvar as $itemvar}</varname> 
 10 </para>
 11 <para>
 12  <varname>{foreach $arrayvar as $keyvar=>$itemvar}</varname> 
 13 </para>
 14 <note>
 15 <para>
 16  This foreach syntax does not accept any named attributes. This syntax is new to Smarty 3, however the Smarty 2.x syntax <literal>{foreach from=$myarray key="mykey" item="myitem"}</literal> is still supported.
 17 </para>
 18 </note>
 19   <itemizedlist>
 20   <listitem><para>
 21   <varname>{foreach}</varname> loops can be nested.
 22   </para></listitem>
 23
 24   <listitem><para>
 25   The <parameter>array</parameter> variable, usually an array of values,
 26   determines the number of times <varname>{foreach}</varname> will loop. You can also pass an integer for arbitrary loops.
 27   </para></listitem>
 28
 29   <listitem><para>
 30   <varname>{foreachelse}</varname> is executed when there are no
 31   values in the <parameter>array</parameter> variable.
 32   </para></listitem>
 33    
 34  <listitem>
 35   <para>
 36    <varname>{foreach}</varname> properties are
 37    <link linkend="foreach.property.index"><parameter>@index</parameter></link>,
 38    <link linkend="foreach.property.iteration"><parameter>@iteration</parameter></link>,
 39    <link linkend="foreach.property.first"><parameter>@first</parameter></link>,
 40    <link linkend="foreach.property.last"><parameter>@last</parameter></link>,
 41    <link linkend="foreach.property.show"><parameter>@show</parameter></link>,
 42    <link linkend="foreach.property.total"><parameter>@total</parameter></link>.
 43   </para>
 44  </listitem>
 45  
 46  <listitem>
 47   <para>
 48    <varname>{foreach}</varname> constructs are
 49    <link linkend="foreach.construct.break"><varname>{break}</varname></link>,
 50    <link linkend="foreach.construct.continue"><varname>{continue}</varname></link>.
 51   </para>
 52  </listitem>
 53        
 54    <listitem><para>
 55     Instead of specifying the <parameter>key</parameter> variable you can access the current key of the
 56     loop item by <parameter>{$item@key}</parameter> (see examples below).
 57    </para></listitem>    
 58    
 59   </itemizedlist> 
 60 
 61   <note>
 62   <para>
 63    The <literal>$var@property</literal> syntax is new to Smarty 3, however when using the Smarty 2 <literal>{foreach from=$myarray key="mykey" item="myitem"}</literal> style syntax, the <literal>$smarty.foreach.name.property</literal> syntax is still supported.
 64   </para>
 65   </note>  
 66   <note>
 67   <para>
 68    Although you can retrieve the array key with the syntax <literal>{foreach $myArray as $myKey => $myValue}</literal>, the key is always available as <varname>$myValue@key</varname> within the foreach loop.
 69   </para>
 70   </note>
 71 
 72 
 73 <para><emphasis role="bold">Option Flags:</emphasis></para>
 74 <informaltable frame="all">
 75  <tgroup cols="2">
 76   <colspec colname="param" align="center" />
 77   <colspec colname="desc" />
 78   <thead>
 79    <row>
 80     <entry>Name</entry>
 81     <entry>Description</entry>
 82    </row>
 83   </thead>
 84   <tbody>
 85    <row>
 86     <entry>nocache</entry>
 87     <entry>Disables caching of the <varname>{foreach}</varname> loop</entry>
 88    </row>
 89   </tbody>
 90  </tgroup>
 91 </informaltable>
 92 
 93 
 94 <example>
 95  <title>A simple <varname>{foreach}</varname> loop</title>
 96  <programlisting role="php">
 97<![CDATA[
 98<?php
 99$arr = array('red', 'green', 'blue');
100$smarty->assign('myColors', $arr);
101?>
102]]>
103  </programlisting>
104   <para>Template to output <parameter>$myColors</parameter> in an un-ordered list</para>
105  <programlisting>
106<![CDATA[
107<ul>
108{foreach $myColors as $color}
109    <li>{$color}</li>
110{/foreach}
111</ul>
112]]>
113  </programlisting>
114  <para>
115   The above example will output:
116  </para>
117  <screen>
118<![CDATA[
119<ul>
120    <li>red</li>
121    <li>green</li>
122    <li>blue</li>
123</ul>
124]]>
125  </screen>
126 </example>
127
128<example>
129  <title>Demonstrates the an additional <parameter>key</parameter> variable</title>
130  <programlisting role="php">
131<![CDATA[
132<?php
133$people = array('fname' => 'John', 'lname' => 'Doe', 'email' => 'j.doe@example.com');
134$smarty->assign('myPeople', $people);
135?>
136]]>
137  </programlisting>
138   <para>Template to output <parameter>$myArray</parameter> as key/value pairs.</para>
139  <programlisting>
140<![CDATA[
141<ul>
142{foreach $myPeople as $value}
143   <li>{$value@key}: {$value}</li>
144{/foreach}
145</ul>
146]]>
147  </programlisting>
148  <para>
149   The above example will output:
150  </para>
151  <screen>
152<![CDATA[
153<ul>
154    <li>fname: John</li>
155    <li>lname: Doe</li>
156    <li>email: j.doe@example.com</li>
157</ul>
158]]>
159  </screen>
160 </example>
161
162
163
164 <example>
165  <title>{foreach} with nested <parameter>item</parameter> and <parameter>key</parameter></title>
166  <para>Assign an array to Smarty, the key contains the key for each looped value.</para>
167  <programlisting role="php">
168<![CDATA[
169<?php
170 $smarty->assign('contacts', array(
171                             array('phone' => '555-555-1234',
172                                   'fax' => '555-555-5678',
173                                   'cell' => '555-555-0357'),
174                             array('phone' => '800-555-4444',
175                                   'fax' => '800-555-3333',
176                                   'cell' => '800-555-2222')
177                             ));
178?>
179]]>
180  </programlisting>
181  <para>The template to output <parameter>$contact</parameter>.</para>
182  <programlisting>
183<![CDATA[
184{* key always available as a property *}
185{foreach $contacts as $contact}
186  {foreach $contact as $value}
187    {$value@key}: {$value}
188  {/foreach}
189{/foreach}
190
191{* accessing key the PHP syntax alternate *}
192{foreach $contacts as $contact}
193  {foreach $contact as $key => $value}
194    {$key}: {$value}
195  {/foreach}
196{/foreach}
197]]>
198  </programlisting>
199  <para>
200   Either of the above examples will output:
201  </para>
202  <screen>
203<![CDATA[
204  phone: 555-555-1234
205  fax: 555-555-5678
206  cell: 555-555-0357
207  phone: 800-555-4444
208  fax: 800-555-3333
209  cell: 800-555-2222
210]]>
211  </screen>
212 </example>
213
214 <example>
215  <title>Database example with {foreachelse}</title>
216  <para>A database (PDO) example of looping over search results. This example is looping over a PHP iterator instead of an array().</para>
217<programlisting role="php">
218<![CDATA[
219<?php 
220  include('Smarty.class.php'); 
221
222  $smarty = new Smarty; 
223
224  $dsn = 'mysql:host=localhost;dbname=test'; 
225  $login = 'test'; 
226  $passwd = 'test'; 
227
228  // setting PDO to use buffered queries in mysql is 
229  // important if you plan on using multiple result cursors 
230  // in the template. 
231
232  $db = new PDO($dsn, $login, $passwd, array( 
233     PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true)); 
234
235  $res = $db->prepare("select * from users"); 
236  $res->execute(); 
237  $res->setFetchMode(PDO::FETCH_LAZY); 
238
239  // assign to smarty 
240  $smarty->assign('res',$res); 
241
242  $smarty->display('index.tpl');?>
243?>
244]]>
245  </programlisting>
246  <programlisting>
247<![CDATA[
248{foreach $res as $r} 
249  {$r.id} 
250  {$r.name}
251{foreachelse}
252  .. no results .. 
253{/foreach}
254]]>
255  </programlisting>
256 </example>
257
258 <para>
259   The above is assuming the results contain the columns named <literal>id</literal> and <literal>name</literal>.
260 </para>
261 <para>
262   What is the advantage of an iterator vs. looping over a plain old array? With an array, all the results are accumulated into memory before being looped. With an iterator, each result is loaded/released within the loop. This saves processing time and memory, especially for very large result sets.
263 </para>
264
265 <sect2 id="foreach.property.index">
266  <title>@index</title>
267  <para>
268   <parameter>index</parameter> contains the current array index, starting with zero.
269  </para>
270  <example>
271  <title><parameter>index</parameter> example</title>
272
273   <programlisting>
274<![CDATA[
275{* output empty row on the 4th iteration (when index is 3) *}
276<table>
277{foreach $items as $i}
278  {if $i@index eq 3}
279     {* put empty table row *}
280     <tr><td>nbsp;</td></tr>
281  {/if}
282  <tr><td>{$i.label}</td></tr>
283{/foreach}
284</table>
285]]>
286  </programlisting>
287  </example>
288  </sect2>
289
290 <sect2 id="foreach.property.iteration">
291  <title>@iteration</title>
292  <para>
293   <parameter>iteration</parameter> contains the current loop iteration and always
294   starts at one, unlike <link linkend="foreach.property.index"><parameter>index</parameter></link>.
295   It is incremented by one on each iteration.
296  </para>
297 <example>
298  <title><parameter>iteration</parameter> example: is div by</title>
299  <para>
300    The <emphasis>"is div by"</emphasis> operator can be used to detect a specific iteration. Here we bold-face the name every 4th iteration.
301  </para>
302  <programlisting>
303<![CDATA[
304{foreach $myNames as $name}
305  {if $name@iteration is div by 4}
306    <b>{$name}</b>
307  {/if}
308  {$name}
309{/foreach}
310]]>
311</programlisting> 
312 </example>
313  <example>
314   <title><parameter>iteration</parameter> example: is even/odd by</title>
315   <para>
316     The <emphasis>"is even by"</emphasis> and <emphasis>"is odd by"</emphasis> 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.
317   </para>
318   <programlisting>
319 <![CDATA[
320 {foreach $myNames as $name}
321   {if $name@iteration is even by 3}
322     <span style="color: #000">{$name}</span>
323   {else}
324     <span style="color: #eee">{$name}</span>
325   {/if}
326 {/foreach}
327 ]]>
328 </programlisting> 
329 
330   <para>
331    This will output something similar to this:
332   </para>
333   <screen>
334<![CDATA[
335    <span style="color: #000">...</span>
336    <span style="color: #000">...</span>
337    <span style="color: #000">...</span>
338    <span style="color: #eee">...</span>
339    <span style="color: #eee">...</span>
340    <span style="color: #eee">...</span>
341    <span style="color: #000">...</span>
342    <span style="color: #000">...</span>
343    <span style="color: #000">...</span>
344    <span style="color: #eee">...</span>
345    <span style="color: #eee">...</span>
346    <span style="color: #eee">...</span>
347    ...
348]]>
349   </screen>
350 
351  </example>
352 </sect2>
353
354 <sect2 id="foreach.property.first">
355  <title>@first</title>
356  <para>
357   <parameter>first</parameter> is &true; if the current <varname>{foreach}</varname>
358   iteration is the initial one. Here we display a table header row on the first iteration.
359  </para>
360  <example>
361  <title><parameter>first</parameter> property example</title>
362   <programlisting>
363<![CDATA[
364{* show table header at first iteration *}
365<table>
366{foreach $items as $i}
367  {if $i@first}
368    <tr>
369      <th>key</td>
370      <th>name</td>
371    </tr>
372  {/if}
373  <tr>
374    <td>{$i@key}</td>
375    <td>{$i.name}</td>
376  </tr>
377{/foreach}
378</table>
379]]>
380  </programlisting>
381  </example>
382 </sect2>
383
384 <sect2 id="foreach.property.last">
385  <title>@last</title>
386  <para>
387   <parameter>last</parameter> is set to &true; if the current
388   <varname>{foreach}</varname> iteration is the final one. Here we display a horizontal rule on the last iteration.
389  </para>
390   <example>
391  <title><parameter>last</parameter> property example</title>
392    <programlisting>
393<![CDATA[
394{* Add horizontal rule at end of list *}
395{foreach $items as $item}
396  <a href="#{$item.id}">{$item.name}</a>{if $item@last}<hr>{else},{/if}
397{foreachelse}
398  ... no items to loop ...
399{/foreach}
400]]>
401  </programlisting>
402   </example>
403 </sect2>
404
405 <sect2 id="foreach.property.show">
406  <title>@show</title>
407  <para>
408   The show <parameter>show</parameter> property can be used after the execution of a
409   <varname>{foreach}</varname> loop to detect if data has been displayed or not.
410   <parameter>show</parameter> is a boolean value.
411  </para>
412  <example>
413   <title><parameter>show</parameter> property example</title>
414   <programlisting>
415<![CDATA[
416<ul>
417{foreach $myArray as $name}
418    <li>{$name}</li>
419{/foreach}
420</ul>
421{if $name@show} do something here if the array contained data {/if}
422]]>
423</programlisting>
424</example>
425 </sect2>
426
427 <sect2 id="foreach.property.total">
428  <title>@total</title>
429  <para>
430   <parameter>total</parameter> contains the number of iterations that this
431   <varname>{foreach}</varname>  will loop.
432   This can be used inside or after the <varname>{foreach}</varname>.
433  </para>
434     <example>
435  <title><parameter>total</parameter> property example</title>
436<programlisting>
437<![CDATA[
438{* show number of rows at end *}
439{foreach $items as $item}
440  {$item.name}<hr/>
441  {if $item@last}
442    <div id="total">{$item@total} items</div>
443  {/if}
444{foreachelse}
445 ... no items to loop ...
446{/foreach}
447]]>
448</programlisting>
449</example>
450
451  <para>
452   See also <link linkend="language.function.section"><varname>{section}</varname></link>,
453   <link linkend="language.function.for"><varname>{for}</varname></link>
454   and
455   <link linkend="language.function.while"><varname>{while}</varname></link>
456  </para>
457
458 </sect2>
459 
460 <sect2 id="foreach.construct.break">
461  <title>{break}</title>
462  <para>
463   <varname>{break}</varname> aborts the iteration of the array
464  </para>
465  <example>
466   <title><varname>{break}</varname> example</title>
467   <programlisting>
468 <![CDATA[
469  {$data = [1,2,3,4,5]}
470  {foreach $data as $value}
471    {if $value == 3}
472      {* abort iterating the array *}
473      {break}
474    {/if}
475    {$value}
476  {/foreach}
477  {*
478    prints: 1 2
479  *}
480 ]]>
481   </programlisting>
482  </example>
483 </sect2>
484 
485 <sect2 id="foreach.construct.continue">
486  <title>{continue}</title>
487  <para>
488   <varname>{continue}</varname> leaves the current iteration and begins with the next iteration.
489  </para>
490  <example>
491   <title><varname>{continue}</varname> example</title>
492   <programlisting>
493 <![CDATA[
494  {$data = [1,2,3,4,5]}
495  {foreach $data as $value}
496    {if $value == 3}
497      {* skip this iteration *}
498      {continue}
499    {/if}
500    {$value}
501  {/foreach}
502  {*
503    prints: 1 2 4 5
504  *}
505 ]]>
506   </programlisting>
507  </example>
508 </sect2>
509 
510</sect1>
511
512<!-- Keep this comment at the end of the file
513 Local variables:
514 mode: sgml
515 sgml-omittag:t
516 sgml-shorttag:t
517 sgml-minimize-attributes:nil
518 sgml-always-quote-attributes:t
519 sgml-indent-step:1
520 sgml-indent-data:t
521 indent-tabs-mode:nil
522 sgml-parent-document:nil
523 sgml-default-dtd-file:"../../../../manual.ced"
524 sgml-exposed-tags:nil
525 sgml-local-catalogs:nil
526 sgml-local-ecat-files:nil
527 End:
528 vim600: syn=xml fen fdm=syntax fdl=2 si
529 vim: et tw=78 syn=sgml
530 vi: ts=1 sw=1
531-->