{section},{sectionelse}

    {section}用来循环数据的数组,而{foreach}用来循环一个单一关联数组。每个{section}标记必须由配对的{/section}标记关闭。

属性名 类型 必需? 缺省 描述
namestringYesn/a 段落的名称
loopmixedYesn/a 确定循环次数的值
startintegerNo0 循环开始时的索引位置。如果是赋值,那么开始位置是从数组的尾部开始计算。例如,如果循环数组里有七个值,而start为-2,那么开始的索引为5。不合法的值(取值超过了循环数组的长度)会自动被截取到最接近的合法值。
stepintegerNo1 step值用来在循环数组中遍历。例如,step=2将循环在索引0,2,4上。如果step为负值,循环从数组的结尾向前进行。
maxintegerNon/a 设置循环最多执行几次。
showbooleanNoTRUE 指定是否要显示本section

例子7-30. 用{section}循环一个简单数组

    从PHP脚本中assign()一个数组给Smarty:

<?php
$data 
= array(1000,1001,1002);
$smarty->assign('custid',$data);
?>

    输出数组的模板:

{* 本例将打印出$custid数组的所有值 *}
{section name=customer loop=$custid}
  id: {$custid[customer]}<br />
{/section}
<hr />
{*  逆序打印所有$custid数组中的值 *}
{section name=foo loop=$custid step=-1}
  {$custid[foo]}<br />
{/section}

    上例将输出:

id: 1000<br />
id: 1001<br />
id: 1002<br />
<hr />
id: 1002<br />
id: 1001<br />
id: 1000<br />

例子7-31. 不带数组赋值的{section}

{section name=foo start=10 loop=20 step=2}
  {$smarty.section.foo.index}
{/section}
<hr />
{section name=bar loop=21 max=6 step=-2}
  {$smarty.section.bar.index}
{/section}

    上例将输出:

10 12 14 16 18
<hr />
20 18 16 14 12 10

例子7-32. 命名一个{section}

    {section}name可以是任何内容,参见PHP变量。它用来引用{section}中的数据。

{section name=anything loop=$myArray}
  {$myArray[anything].foo}
  {$name[anything]}
  {$address[anything].bar}
{/section}

例子7-33. 用{section}循环一个关联数组

    下例用{section}来打印一个关联数组的数据。下面的PHP脚本将$contacts数组赋值给Smarty。

<?php
$data 
= array(
          array(
'name' => 'John Smith''home' => '555-555-5555',
                
'cell' => '666-555-5555''email' => 'john@myexample.com'),
          array(
'name' => 'Jack Jones''home' => '777-555-5555',
                
'cell' => '888-555-5555''email' => 'jack@myexample.com'),
          array(
'name' => 'Jane Munson''home' => '000-555-5555',
                
'cell' => '123456''email' => 'jane@myexample.com')
        );
$smarty->assign('contacts',$data);
?>

    输出$contacts的模板:

{section name=customer loop=$contacts}
<p>
  name: {$contacts[customer].name}<br />
  home: {$contacts[customer].home}<br />
  cell: {$contacts[customer].cell}<br />
  e-mail: {$contacts[customer].email}
</p>
{/section}

    上例的输出为:

<p>
  name: John Smith<br />
  home: 555-555-5555<br />
  cell: 666-555-5555<br />
  e-mail: john@myexample.com
</p>
<p>
  name: Jack Jones<br />
  home phone: 777-555-5555<br />
  cell phone: 888-555-5555<br />
  e-mail: jack@myexample.com
</p>
<p>
  name: Jane Munson<br />
  home phone: 000-555-5555<br />
  cell phone: 123456<br />
  e-mail: jane@myexample.com
</p>

例子7-34. 展示{section}的loop变量

    本例中假定$custid$name以及$address都是包含相同数量的值数组。首先PHP脚本将这些数组赋值给Smarty。

<?php

$id 
= array(1001,1002,1003);
$smarty->assign('custid',$id);

$fullnames = array('John Smith','Jack Jones','Jane Munson');
$smarty->assign('name',$fullnames);

$addr = array('253 Abbey road''417 Mulberry ln''5605 apple st');
$smarty->assign('address',$addr);

?>

    loop变量只是确定循环的次数。你可以在{section}里存取任何模板中的变量:

{section name=customer loop=$custid}
<p>
  id: {$custid[customer]}<br />
  name: {$name[customer]}<br />
  address: {$address[customer]}
</p>
{/section}

    上例将输出:

<p>
  id: 1000<br />
  name: John Smith<br />
  address: 253 Abbey road
</p>
<p>
  id: 1001<br />
  name: Jack Jones<br />
  address: 417 Mulberry ln
</p>
<p>
  id: 1002<br />
  name: Jane Munson<br />
  address: 5605 apple st
</p>

例子7-35. 嵌套的{section}

    段落可以嵌套,深度不限。通过嵌套段落,你可以存取非常复杂的数据结构,如多维数组等。下面的PHP脚本赋值数组给Smarty:

<?php

$id 
= array(1001,1002,1003);
$smarty->assign('custid',$id);

$fullnames = array('John Smith','Jack Jones','Jane Munson');
$smarty->assign('name',$fullnames);

$addr = array('253 N 45th''417 Mulberry ln''5605 apple st');
$smarty->assign('address',$addr);

$types = array(
           array( 
'home phone''cell phone''e-mail'),
           array( 
'home phone''web'),
           array( 
'cell phone')
         );
$smarty->assign('contact_type'$types);

$info = array(
           array(
'555-555-5555''666-555-5555''john@myexample.com'),
           array( 
'123-456-4''www.example.com'),
           array( 
'0457878')
        );
$smarty->assign('contact_info'$info);

?>

    本模板中,$contact_type[customer]是当前客户的联系方法类型。

{section name=customer loop=$custid}
<hr>
  id: {$custid[customer]}<br />
  name: {$name[customer]}<br />
  address: {$address[customer]}<br />
  {section name=contact loop=$contact_type[customer]}
    {$contact_type[customer][contact]}: {$contact_info[customer][contact]}<br />
  {/section}
{/section}

    上例的输出为:

<hr>
  id: 1000<br />
  name: John Smith<br />
  address: 253 N 45th<br />
    home phone: 555-555-5555<br />
    cell phone: 666-555-5555<br />
    e-mail: john@myexample.com<br />
<hr>
  id: 1001<br />
  name: Jack Jones<br />
  address: 417 Mulberry ln<br />
    home phone: 123-456-4<br />
    web: www.example.com<br />
<hr>
  id: 1002<br />
  name: Jane Munson<br />
  address: 5605 apple st<br />
    cell phone: 0457878<br />

例子7-36. 带有{sectionelse}的数据库例子

    数据库搜索的结果(ADODB或PEAR)传递给Smarty:

<?php
$sql 
'select id, name, home, cell, email from contacts '
      
."where name like '$foo%' ";
$smarty->assign('contacts'$db->getAll($sql));
?>

    下面的模板将结果以HTML表格的方式输出:

<table>
<tr><th>&nbsp;</th><th>Name></th><th>Home</th><th>Cell</th><th>Email</th></tr>
{section name=co loop=$contacts}
  <tr>
    <td><a href="view.php?id={$contacts[co].id}">view<a></td>
    <td>{$contacts[co].name}</td>
    <td>{$contacts[co].home}</td>
    <td>{$contacts[co].cell}</td>
    <td>{$contacts[co].email}</td>
  <tr>
{sectionelse}
  <tr><td colspan="5">No items found</td></tr>
{/section}
</table>

.index

    index包含但前数组的索引,起始为0或者start 属性如果指定的话)。它每次循环增加1或者step值(如果指定的话)。

技术注解:如果不指定stepstart属性,那么这个属性和iteration属性是一样的,只是它从0开始,而不是从1开始。

例子7-37. {section}索引属性

FYI: $custid[customer.index]$custid[customer]的含义是一样的。

{section name=customer loop=$custid}
  {$smarty.section.customer.index} id: {$custid[customer]}<br />
{/section}

    上例的输出为:

0 id: 1000<br />
1 id: 1001<br />
2 id: 1002<br />

.index_prev

    index_prev是循环的上一个索引。在第一次循环时,设置为-1。

.index_next

    index_next是循环的下一个索引。在最后一次循环时,它比当前所以大1,当然要考虑step属性(如果指定的话)。

例子7-38. indexindex_nextindex_prev属性

<?php
$data 
= array(1001,1002,1003,1004,1005);
$smarty->assign('rows',$data);
?>

    下面的模板将上面的数组输出为表格:

{* $rows[row.index]和$rows[row]的含义是一样的 *}
<table>
  <tr>
    <th>index</th><th>id</th>
    <th>index_prev</th><th>prev_id</th>
    <th>index_next</th><th>next_id</th>
  </tr>
{section name=row loop=$rows}
  <tr>
    <td>{$smarty.section.row.index}</td><td>{$rows[row]}</td>
    <td>{$smarty.section.row.index_prev}</td><td>{$rows[row.index_prev]}</td>
    <td>{$smarty.section.row.index_next}</td><td>{$rows[row.index_next]}</td>
  </tr>
{/section}
</table>

    上例会输出包含如下内容的表格:

index  id    index_prev prev_id index_next next_id
0      1001  -1	                1          1002
1      1002  0          1001    2          1003
2      1003  1          1002    3          1004
3      1004  2          1003    4          1005
4      1005  3          1004    5

.iteration

    iteration包含当前循环的循环次数,从1开始。

注意:index属性不同,它不受{section}属性startstepmax的影响。iterationindex不同的是,它从1开始而不是从0开始。rownumiteration的别名,它们是同一的。

例子7-39. section的iteration属性

<?php
// array of 3000 to 3015
$id range(3000,3015);
$smarty->assign('arr',$id);
?>

    每隔一个输出$arr元素的模板,因为step=2:

{section name=cu loop=$arr start=5 step=2}
  iteration={$smarty.section.cu.iteration}
  index={$smarty.section.cu.index}
  id={$custid[cu]}<br />
{/section}

    上例将输出:

iteration=1 index=5 id=3005<br />
iteration=2 index=7 id=3007<br />
iteration=3 index=9 id=3009<br />
iteration=4 index=11 id=3011<br />
iteration=5 index=13 id=3013<br />
iteration=6 index=15 id=3015<br />

    下面是另一个例子,使用iteration属性每隔5行输出表格头,其中使用了{if}和取余运算:

<table>
{section name=co loop=$contacts}
  {if $smarty.section.co.iteration % 5 == 1}
    <tr><th>&nbsp;</th><th>Name></th><th>Home</th><th>Cell</th><th>Email</th></tr>
  {/if}
  <tr>
    <td><a href="view.php?id={$contacts[co].id}">view<a></td>
    <td>{$contacts[co].name}</td>
    <td>{$contacts[co].home}</td>
    <td>{$contacts[co].cell}</td>
    <td>{$contacts[co].email}</td>
  <tr>
{/section}
</table>

.first

    first为真,当目前的{section}循环是第一个时。

.last

    last为真,当目前的{section}循环为最后一个时。

例子7-40. {section}属性:firstlast

    本例中,循环$customers数组,在第一个循环时输出头,最后一个循环时输出脚注。同时用到了total属性。

{section name=customer loop=$customers}
  {if $smarty.section.customer.first}
    <table>
    <tr><th>id</th><th>customer</th></tr>
  {/if}

  <tr>
    <td>{$customers[customer].id}}</td>
    <td>{$customers[customer].name}</td>
  </tr>

  {if $smarty.section.customer.last}
    <tr><td></td><td>{$smarty.section.customer.total} customers</td></tr>
    </table>
  {/if}
{/section}

.rownum

    rownum包含的是当前循环次数,从1开始。它是iteration的别名,它们是一样的。

.loop

    loop包含的是本{section}循环的最后一个索引数目。可以在{section}之内或之后使用。

例子7-41. {section}属性:loop

{section name=customer loop=$custid}
  {$smarty.section.customer.index} id: {$custid[customer]}<br />
{/section}
There are {$smarty.section.customer.loop} customers shown above.

    上例将输出:

0 id: 1000<br />
1 id: 1001<br />
2 id: 1002<br />
There are 3 customers shown above.

.show

    show可以作为section的参数。show是个布尔值。如果是FALSE,该段落不会被显示。此时如果有{sectionelse},将显示其内容。

例子7-42. show属性

    布尔值$show_customer_info从PHP应用中传递,来控制是否显示本段落。

{section name=customer loop=$customers show=$show_customer_info}
  {$smarty.section.customer.rownum} id: {$customers[customer]}<br />
{/section}

{if $smarty.section.customer.show}
  the section was shown.
{else}
  the section was not shown.
{/if}

    上例将显示:

1 id: 1000<br />
2 id: 1001<br />
3 id: 1002<br />

the section was shown.

.total

    total包含该{section}将循环的次数。可以用在{section}之中或之后。

例子7-43. total属性例子

{section name=customer loop=$custid step=2}
  {$smarty.section.customer.index} id: {$custid[customer]}<br />
{/section}
   There are {$smarty.section.customer.total} customers shown above.

    参见{foreach}$smarty.section