Smarty简介
为何使用Smarty?
用例和工作流
语法比较
模板继承
最佳实践
快速教程
{section}
用于循环遍历按顺序编索引的数据数组,这与用于循环遍历单个关联数组的 {foreach}
不同。每个 {section}
标记都必须与一个关闭的 {/section}
标记配对。
和 {foreach} 循环能实现 {section} 能实现的所有功能,并且语法更简单。通常最好使用 {foreach} 循环。
{section} 循环无法循环遍历关联数组,它们必须按数字索引,并且按顺序排列 (0、1、2、...)。对于关联数组,请使用 {foreach}
循环。
属性名称 | 类型 | 必需 | 默认值 | 说明 |
---|---|---|---|---|
name | 字符串 | 是 | n/a | 节的名称 |
loop | 混合 | 是 | n/a | 确定循环迭代次数的值 |
start | 整数 | 否 | 0 | 循环遍历的起始索引位置。如果值为负数,则从数组末尾计算开始位置。例如,如果循环数组中有七个值,且 start 为 -2,则起始索引为 5。无效值(数组长度之外的值)会自动截断到最接近的有效值。 |
step | 整数 | 否 | 1 | 用于遍历循环数组的 step 值。例如,step=2 将在索引 0、2、4 等等循环。如果 step 为负数,则将向后退经数组。 |
max | 整数 | 否 | n/a | 设置节循环的最大次数。 |
show | 布尔值 | 否 | TRUE |
确定是否显示此节 |
选项标记
名称 | 说明 |
---|---|
nocache | 禁用 {section} 循环的缓存 |
必需属性为name
和 loop
。
{section}
的 name
可以由字母、数字和下划线组成,就象 PHP 变量 一样。
{section} 可以嵌套,嵌套 {section}
的名称必须是唯一的。
loop
属性通常是一个值组成的数组,它决定了 {section}
的循环次数。你还可以将一个整数传入作为循环值。
当在一个 {section}
内打印一个变量时,{section}
的 name
必须紧跟 [brackets] 中的变量名称。
当循环变量中没有值时,{sectionelse}
将被执行。
{section}
还具有自己的变量,来处理 {section}
属性。这些属性可以用以下方式访问: {$smarty.section.name.property}
其中 “name” 是 name
属性。
{section}
属性有 index
,index_prev
,index_next
,iteration
,first
,last
,rownum
,loop
,show
,total
。
范例 7.63 使用 {section} 循环一个简单的数组
使用 assign()
将数组分配给 Smarty
<?php $data = array(1000,1001,1002); $smarty->assign('custid',$data); ?>
输出数组的模板
{* this example will print out all the values of the $custid array *} {section name=customer loop=$custid} {section customer $custid} {* short-hand *} id: {$custid[customer]}<br /> {/section} <hr /> {* print out all the values of the $custid array reversed *} {section name=foo loop=$custid step=-1} {section foo $custid step=-1} {* short-hand *} {$custid[foo]}<br /> {/section}
上述范例会输出
id: 1000<br /> id: 1001<br /> id: 1002<br /> <hr /> id: 1002<br /> id: 1001<br /> id: 1000<br />
范例 7.64 在没有分配数组的情况下使用 {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.65 给 {section} 命名
{section}
的 name
可以由你喜欢的任何内容组成,请参阅 PHP 变量。它用于引用 {section}
中的数据。
{section name=anything loop=$myArray} {$myArray[anything].foo} {$name[anything]} {$address[anything].bar} {/section}
范例 7.66 使用 {section} 循环一个关联数组
以下是一个使用 {section}
打印一个关联数据数组的范例。接下来是一个 PHP 脚本,用于将 $contacts
数组分配给 Smarty。
<?php $data = array( array('name' => 'John Smith', 'home' => '555-555-5555', 'cell' => '666-555-5555', 'email' => '[email protected]'), array('name' => 'Jack Jones', 'home' => '777-555-5555', 'cell' => '888-555-5555', 'email' => '[email protected]'), array('name' => 'Jane Munson', 'home' => '000-555-5555', 'cell' => '123456', 'email' => '[email protected]') ); $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: [email protected] </p> <p> name: Jack Jones<br /> home phone: 777-555-5555<br /> cell phone: 888-555-5555<br /> e-mail: [email protected] </p> <p> name: Jane Munson<br /> home phone: 000-555-5555<br /> cell phone: 123456<br /> e-mail: [email protected] </p>
示例 7.67. 演示 loop
变量的 {section}
此示例假定 $custid
、$name
和 $address
都是包含相同数量值的数组。首先是分配数组给 Smarty 的 php 脚本。
<?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.68. 嵌套 {section}
{section} 可以嵌套任意深度。利用嵌套 {section},您可以访问复杂的数据结构,例如多维数组。这是一个分配数组的 .php
脚本示例。
<?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', '[email protected]'), 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: [email protected]<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.69. 包含 {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> </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
包含当前数组索引,从零或给定的 start
属性开始。它以一个或给定的 step
属性递增。
如果 step
和 start
属性未修改,则它与 iteration
属性的工作方式相同,但它从零而不是从一开始。
示例 7.70. {section} index
属性
$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_next
是下一个循环索引。在最后一个循环中,它仍然比当前索引大 1,假如已给定,将尊重 step
属性的设置。
示例 7.71. index
、index_next
和 index_prev
属性
<?php $data = array(1001,1002,1003,1004,1005); $smarty->assign('rows',$data); ?>
模板,以表格输出上述数组
{* $rows[row.index] and $rows[row] are identical in meaning *} <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
包含当前循环迭代,且从 1 开始。
这不受 {section}
属性 start
、step
和 max
影响,这与 index
属性不同。iteration
也从 1 开始,而不是像 index
一样从 0 开始。rownum
是 iteration
的别名,它们是相同的。
示例 7.72。节的 iteration
属性
<?php // array of 3000 to 3015 $id = range(3000,3015); $smarty->assign('arr',$id); ?>
以 step=2
为模版输出 $arr
数组的每一个其他元素
{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
属性每五行为表格表头块输出的示例。
<table> {section name=co loop=$contacts} {if $smarty.section.co.iteration is div by 5} <tr><th> </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>
使用 iteration
属性每三行交替一次文本颜色的示例。
<table> {section name=co loop=$contacts} {if $smarty.section.co.iteration is even by 3} <span style="color: #ffffff">{$contacts[co].name}</span> {else} <span style="color: #dddddd">{$contacts[co].name}</span> {/if} {/section} </table>
“is div by” 语法是 PHP mod 运算符语法的更简单的替代方案。允许使用 mod 运算符:{if $smarty.section.co.iteration % 5 == 1}
执行方式相同。
你还可以使用 “is odd by” 来颠倒交替方式。
如果当前节迭代是最终迭代,则 last
设置为 TRUE
。
示例 7.73。{section} 属性 first
和 last
此示例循环遍历 $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
包含当前的循环迭代,从 1 开始。它是 iteration
的别名,它们的工作方式相同。
loop
包含此 {section} 循环的最后一个索引号。这可用于 {section}
内部或之后。
示例 7.74。{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
被用作节的参数,并且是一个布尔值。如果为 FALSE
,则不会显示该节。如果存在 {sectionelse}
,则会交替显示它。
示例 7.75。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
包含此 {section}
将进行的迭代次数。可以在 {section}
内部或之后使用此字段。
示例 7.76. 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}
、{for}
、{while}
以及 $smarty.section
。