ECJiaWiki:Smarty:内置函数

来自ECJiaWiki
跳转至: 导航搜索
ECJia到家Smarty模版手册导航
为什么选择Smarty?
基本语法-变量
基本语法-函数
基本语法-属性
基本语法-双引号中嵌入变量
基本语法-数学计算
从PHP赋值的变量
Smarty保留变量
变量修饰器
内置函数
自定义函数

内置函数

Smarty自带了一些内置函数。 这些内置函数是Smarty模板引擎的组成部分。 它们会被编译到PHP代码中,以取得最高的性能。

你不能建立相同名称的自定义函数; 同时你也不需要修改这些内置函数。

少数的内置函数有assign属性, 可以将函数的结果赋值给模板变量,而不是输出; 效果如同 {assign}函数。

{$var=...}

{assign}函数的缩写。你可以在模板内对变量进行赋值,或者对数组元素进行赋值。

Note

在模板中进行赋值,从根本上讲还是将程序逻辑放到显示层来进行了,在PHP端进行此操作会更好。请自行考虑。

下面是该标签的属性:

属性:

参数名称 缩写 类型 必选参数 默认值 说明
scpe n/a string No n/a 变量的作用范围: 'parent','root' 或 'global'


可选标记:

名称 说明
nocache 对赋值操作不进行缓存

示例:

【简单赋值】
{$name='Bob'}
The value of $name is {$name}.
  
输出: 
The value of $name is Bob.  


【数学运算赋值】
{$running_total=$running_total+$some_array[row].some_value}  


【对数组元素赋值】
{$user.name="Bob"}  


【对多维数组元素赋值】
{$user.name.first="Bob"}  


【附加到数组】
{$users[]="Bob"}  


【赋值的作用范围】
在包含的模板内赋值的变量,在包含模板内可见。
{include file="sub_template.tpl"}
...
{* display variable assigned in sub_template *}
{$foo}<br>
...  
上面的模板是包含了下面的模板sub_template.tpl
...
{* foo will be known also in the including template *}
{$foo="something" scope=parent}
{* bar is assigned only local in the including template *}
{$bar="value"}
...

{append}

{append}可以在 运行时 为数组变量增加或者创建值。

Note

这需要考虑的是,对于模板中变量的赋值,最好尽量是放到PHP程序代码中进行。

属性:

参数名称 缩写 类型 默认值 说明
var string yes n/s 赋值变量名称
value string yes n/s 赋予的值
index string No n/s 数组元素的新索引,如果没有提供此参数,则附加的值会加到数组最后
scope string No n/s 赋值变量的访问范围: 'parent','root' 或 'global'


示例:

{append var='name' value='Bob' index='first'}
{append var='name' value='Meyer' index='last'}
// or 
{append 'name' 'Bob' index='first'} {* short-hand *}
{append 'name' 'Meyer' index='last'} {* short-hand *}

The first name is {$name.first}.<br>
The last name is {$name.last}.

输出: 
The first name is Bob.
The last name is Meyer.
 

{assign}

{assign}用于在模板运行期间赋值给变量.

Note

在模板中进行赋值,从根本上讲还是将程序逻辑放到显示层来进行了,在PHP端进行此操作会更好。请自行考虑。

Note

参见赋值给变量方法的缩写。

属性:

参数名称 类型 必选参数 默认值 说明
var string yes n/s 赋值变量名称
value string yes n/s 赋予的值
scope string yes n/s 变量的作用范围:'parent','root'或'global'

可选标记:

名称 说明
nocache 对赋值操作不进行缓存

示例:

【简单赋值】
{assign var="name" value="Bob"}
{assign "name" "Bob"} {* short-hand *}
The value of $name is {$name}.
  
输出: 
The value of $name is Bob.  


【使用nocache属性】
{assign var="name" value="Bob" nocache}
{assign "name" "Bob" nocache} {* short-hand *}
The value of $name is {$name}.
  
输出: 
The value of $name is Bob.  


【进行数学运算】
{assign var=running_total value=$running_total+$some_array[$row].some_value}  


【在调用的模板内的作用范围】
在包含的模板内赋值的变量,在包含模板内可见。
{include file="sub_template.tpl"}
...
{* display variable assigned in sub_template *}
{$foo}<br>
...
  
上面的模板是包含了下面的模板sub_template.tpl
...
{* foo will be known also in the including template *}
{assign var="foo" value="something" scope=parent}
{* bar is assigned only local in the including template *}
{assign var="bar" value="value"}
...


【作用范围例子】
设置变量访问范围为root,然后该变量在相关模板里面都可见。
{assign var=foo value="bar" scope="root"} 


【赋值一个全局变量】
全局变量在任何模板内均可见。
{assign var=foo value="bar" scope="global"}
{assign "foo" "bar" scope="global"} {* short-hand *}  


【从PHP脚本中获取{assign} 的变量】
可以使用 getTemplateVars()在PHP脚本中获取{assign}的变量值。 这里的模板创建了变量$foo。 
{assign var="foo" value="Smarty"}
当模板被执行时/执行后,可以用以下的方式在PHP获取到这个模板变量。 
<?php
// this will output nothing as the template has not been executed
echo $this->cs->getTemplateVars('foo');

// fetch the template to a variable
$whole_page = $this->cs->fetch('index.tpl');

// this will output 'smarty' as the template has been executed
echo $this->cs->getTemplateVars('foo');

$smarty->assign('foo','Even smarter');

// this will output 'Even smarter'
echo $this->cs->getTemplateVars('foo');
?>

{block}

{block}可在模板上定义一块区域,以进行模板继承。

子模板中的{block}区域代码,将会替换父模板对应的区域代码。

另外,{block}可以设置成合并父子模板的相应区域。在子模板的{block}中定义 append 或 prepend,可以使子模板附加在父模板 {block}区域的后面或前面。 在{block}内容中使用{$smarty.block.parent},可以让父模板的区域代码放到 子模板{block}内的任何位置。

{blocks}可以嵌套使用。

属性:

参数名称 类型 必选参数 默认值 说明
name string yes n/s 模板区域的名称

可选属性 (仅在子模板中使用):

名称 说明
append {block}区域代码将附加到父模板的{block}内容之后
prepend {block}区域代码将附加到父模板的{block}内容之前
hide 在没有该名称区域的时候,忽略区域内容。
nocache 关闭{block} 缓存


例子:

【简单的 {block} 例子】

parent.tpl

<html>
  <head>
    <title>{block name="title"}Default Title{/block}</title>
    <title>{block "title"}Default Title{/block}</title>  {* short-hand  *}
  </head>
</html>
  
child.tpl

{extends file="parent.tpl"} 
{block name="title"}
Page Title
{/block}
  
结果输出:

<html>
  <head>
    <title>Page Title</title>
  </head>
</html>


【前面附加 {block} 例子】

parent.tpl

<html>
  <head>
    <title>{block name="title"}Title - {/block}</title>
  </head>
</html>
  
child.tpl

{extends file="parent.tpl"} 
{block name="title" prepend}
Page Title
{/block}
  
结果输出

<html>
  <head>
    <title>Title - Page Title</title>
  </head>
</html>


【后面附加 {block} 例子】

parent.tpl

<html>
  <head>
    <title>{block name="title"} is my title{/block}</title>
  </head>
</html>
  
child.tpl

{extends file="parent.tpl"} 
{block name="title" append}
Page Title
{/block}
  
结果输出:

<html>
  <head>
    <title>Page title is my titel</title>
  </head>
</html>


【{$smarty.block.child} 例子】

parent.tpl

<html>
  <head>
    <title>{block name="title"}The {$smarty.block.child} was inserted here{/block}</title>
  </head>
</html>
  
child.tpl

{extends file="parent.tpl"} 
{block name="title"}
Child Title
{/block}
  
结果输出:

<html>
  <head>
    <title>The Child Title was inserted here</title>
  </head>
</html>


【{$smarty.block.parent} 例子】

parent.tpl

<html>
  <head>
    <title>{block name="title"}Parent Title{/block}</title>
  </head>
</html>
  
child.tpl

{extends file="parent.tpl"} 
{block name="title"}
You will see now - {$smarty.block.parent} - here
{/block}
  
结果输出:

<html>
  <head>
    <title>You will see now - Parent Title - here</title>
  </head>
</html>

{call}

{call}可以调用一个通过 {function} 标签来定义的模板函数,如同调用插件函数一样。

Note

模板函数是全局定义的。因为Smarty编译器是一个单次的编译器,所以 {call} 标签调用的函数,务必定义在当前模板之外的位置。 或者你可以直接通过{funcname ...}的方式来使用该函数。

{call}必须设置name属性, 标识要调用的模板函数的名称。

可以按照属性的方式来给函数传递参数。

属性:

参数名称 类型 必选参数 默认值 说明
name string No n/s 模板函数的名称
assign string No n/s 将函数的返回内容赋值到指定变量
[var ...] [var type] No n/s 传递给模板函数的参数

可选的标记:

名称 说明
nocache 以不缓存的模式调用该函数

调用一个递归菜单的例子:

{* define the function *}
{function name=menu level=0}
  <ul class="level{$level}">
  {foreach $data as $entry}
    {if is_array($entry)}
      <li>{$entry@key}</li>
      {call name=menu data=$entry level=$level+1}
    {else}
      <li>{$entry}</li>
    {/if}
  {/foreach}
  </ul>
{/function}

{* create an array to demonstrate *}
{$menu = ['item1','item2','item3' => ['item3-1','item3-2','item3-3' =>
['item3-3-1','item3-3-2']],'item4']}

{* run the array through the function *}
{call name=menu data=$menu}
{call menu data=$menu} {* short-hand *}

输出: 

* item1
* item2
* item3
      o item3-1
      o item3-2
      o item3-3
            + item3-3-1
            + item3-3-2
* item4
 

{capture}

{capture}可以捕获标记范围内的输出内容,存到变量中而不显示。 任何在{capture name='foo'} 和 {/capture} 之间的内容都会被捕获到变量,变量名可以通过name属性来指定。

捕获的内容可以通过$smarty.capture.foo变量来使用,这里foo是设置的name属性。 如果没有提供name属性,默认是“default”,也就是 $smarty.capture.default.

{capture}可以被嵌套使用。

属性:

参数名称 类型 必选参数 默认值 说明
name string yes n/a 捕获区域的名称
assign</] string No n/a 捕获内容后赋值的变量名
append string No n/a 将捕获的内容增加到数组中

可选标记:

名称 说明
nocache 关闭捕获区域的缓存


Note

当捕获{insert}输出的时候请小心。 如果开启了$caching并且 你希望通过{insert} 在缓存的页面上显示动态内容,那么你无法捕获这些内容。

例子:

【{capture}使用name属性】
{* we don't want to print a div tag unless content is displayed *}
{capture name="banner"}
{capture "banner"} {* short-hand *}
  {include file="get_banner.tpl"}
{/capture}

{if $smarty.capture.banner ne ""}
<div id="banner">{$smarty.capture.banner}</div>
{/if} 


【{capture} 捕获内容到变量】
下面是capture函数的演示
{capture name=some_content assign=popText}
{capture some_content assign=popText} {* short-hand *}
The server is {$my_server_name|upper} at {$my_server_addr}<br>
Your ip is {$my_ip}.
{/capture}
<a href="#">{$popText}</a>

     
【{capture} 捕获内容到数组变量】
下面例子演示了如何多次捕获内容,形成数组。 
{capture append="foo"}hello{/capture}I say just {capture append="foo"}world{/capture}
{foreach $foo as $text}{$text} {/foreach}
     
输出: 

I say just hello world

{for}

{for}{forelse}用于创建一个简单的循环。 下面的几种方式都是支持的:

{for $var=$start to $end}步长1的简单循环。

{for $var=$start to $end step $step}指定步长的循环。

{forelse}在循环不能遍历的时候执行。

属性:

参数名称 缩写 类型 必选类型 默认值 说明
max n/a integer No n/a 循环的次数

例子:

【简单的{for} 循环】
<ul>
{for $foo=1 to 3}
    <li>{$foo}</li>
{/for}
</ul>
  
输出: 

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>

  
【使用max 属性】
<ul>
{for $foo=3 to 10 max=3}
    <li>{$foo}</li>
{/for}
</ul>
  
输出: 

<ul>
    <li>3</li>
    <li>4</li>
    <li>5</li>
</ul>

  
【{forelse}的执行】
<ul>
{for $foo=10 to 5}
    <li>{$foo}</li>
{forelse}
  no iteration
{/for}
</ul>

输出: 

  no iteration
 

{foreach},{foreachelse}

{foreach}用于循环数组。 {foreach}的语法比{section}循环要更简单和清晰,并且可以使用非数字下标的数组。

{foreach $arrayvar as $itemvar}

{foreach $arrayvar as $keyvar=>$itemvar}

Note

foreach的语法可以接受没有名称的属性,该语法是Smarty 3新增的。然而Smarty 2语法 {foreach from=$myarray key="mykey" item="myitem"}也同样支持。

{foreach} 循环可以被嵌套使用.

array变量,一般是数组的值,决定了{foreach} 循环的次数。你也可以传递一个任意的整数来控制循环次数。

如果array数组变量中,没有值的情况下, {foreachelse}将执行。

{foreach}的属性: @index, @iteration, @first, @last, @show, @total.

{foreach}的语法命令: {break}, {continue}.

代替指定key变量,你可以通过 {$item@key}来使用循环的当前key。(见下面的例子).

Note

$var@property的语法是Smarty 3新增的。然而Smarty 2风格的语法{foreach from=$myarray key="mykey" item="myitem"}, $smarty.foreach.name.property也是支持的。

Note

即使你在循环语法里{foreach $myArray as $myKey => $myValue} 已经指定了key的变量名,但循环体内$myValue@key还是可用的。

可选标记:

名称 说明 nocache 关闭{foreach}循环的缓存

例子:

【简单的{foreach} 循环】

<?php
$arr = array('red', 'green', 'blue');
$this->cs->assign('myColors', $arr);
?>
  
模板将顺序输出$myColors。

<ul>
{foreach $myColors as $color}
    <li>{$color}</li>
{/foreach}
</ul>
  
输出: 

<ul>
    <li>red</li>
    <li>green</li>
    <li>blue</li>
</ul>

  
【使用key变量的例子】

<?php
$people = array('fname' => 'John', 'lname' => 'Doe', 'email' => 'j.doe@example.com');
$this->cs->assign('myPeople', $people);
?>
  
模板将以键值对的方式输出$myArray

<ul>
{foreach $myPeople as $value}
   <li>{$value@key}: {$value}</li>
{/foreach}
</ul>
  
输出: 

<ul>
    <li>fname: John</li>
    <li>lname: Doe</li>
    <li>email: j.doe@example.com</li>
</ul>  


【多维数组通过item 和 key来嵌套使用{foreach}】

多维数组的键一般会对应另一个数组。

<?php
 $this->cs->assign('contacts', array(
                             array('phone' => '555-555-1234',
                                   'fax' => '555-555-5678',
                                   'cell' => '555-555-0357'),
                             array('phone' => '800-555-4444',
                                   'fax' => '800-555-3333',
                                   'cell' => '800-555-2222')
                             ));
?>
  
模板将输出$contact.

{* key always available as a property *}
{foreach $contacts as $contact}
  {foreach $contact as $value}
    {$value@key}: {$value}
  {/foreach}
{/foreach}

{* accessing key the PHP syntax alternate *}
{foreach $contacts as $contact}
  {foreach $contact as $key => $value}
    {$key}: {$value}
  {/foreach}
{/foreach}
  
上面两个例子都会输出: 

  phone: 555-555-1234
  fax: 555-555-5678
  cell: 555-555-0357
  phone: 800-555-4444
  fax: 800-555-3333
  cell: 800-555-2222

  
【{foreachelse}的数据库例子】

循环显示数据库(PDO)结果。例子是循环了一个PHP的迭代器(iterator)而不是一个数组(array)。

<?php 
  include('Smarty.class.php'); 

  $smarty = new Smarty; 

  $dsn = 'mysql:host=localhost;dbname=test'; 
  $login = 'test'; 
  $passwd = 'test'; 

  // setting PDO to use buffered queries in mysql is 
  // important if you plan on using multiple result cursors 
  // in the template. 

  $db = new PDO($dsn, $login, $passwd, array( 
     PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true)); 

  $res = $db->prepare("select * from users"); 
  $res->execute(); 
  $res->setFetchMode(PDO::FETCH_LAZY); 

  // assign to smarty 
  $smarty->assign('res',$res); 

  $smarty->display('index.tpl');?>
?>

  

{foreach $res as $r} 
  {$r.id} 
  {$r.name}
{foreachelse}
  .. no results .. 
{/foreach}

@index

index是当前数组索引,从0开始计算。

index 例子:

{* output empty row on the 4th iteration (when index is 3) *}
<table>
{foreach $items as $i}
  {if $i@index eq 3}
     {* put empty table row *}
     <tr><td>nbsp;</td></tr>
  {/if}
  <tr><td>{$i.label}</td></tr>
{/foreach}
</table>

@iteration

iteration是当前循环的次数,和index不同,iteration是从1开始。 iteration在每次循环的时候都会加一。

iteration 例子: is div by:

//"is div by"运算可以对循环次数做一些特殊的判断。 下面我们将每4次循环就输出一次粗体的名称。 

{foreach $myNames as $name}
  {if $name@iteration is div by 4}
    <b>{$name}</b>
  {/if}
  {$name}
{/foreach}

iteration 例子: is even/odd by:

//is even by" 和 "is odd by"可以用于在循环中奇偶交替进行一些操作。在开始的时候可以选择奇或偶的循环。 下面是每三次循环会改变一次字体颜色。 
 
 {foreach $myNames as $name}
   {if $name@iteration is even by 3}
     <span style="color: #000">{$name}</span>
   {else}
     <span style="color: #eee">{$name}</span>
   {/if}
 {/foreach} 

输出:

    <span style="color: #000">...</span>
    <span style="color: #000">...</span>
    <span style="color: #000">...</span>
    <span style="color: #eee">...</span>
    <span style="color: #eee">...</span>
    <span style="color: #eee">...</span>
    <span style="color: #000">...</span>
    <span style="color: #000">...</span>
    <span style="color: #000">...</span>
    <span style="color: #eee">...</span>
    <span style="color: #eee">...</span>
    <span style="color: #eee">...</span>
    ...

@first

当循环{foreach}是首次循环时,first将为TRUE 下面我们用first来显示一个表格的表头。

last例子:

{* 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

show属性是在{foreach}循环执行之后, 检测循环是否显示数据的判断。 show是一个布尔值。

show例子: </pre>

    {foreach $myArray as $name}
  • {$name}
  • {/foreach}

{if $name@show} do something here if the array contained data {/if} </pre>

@total

total是整个{foreach}循环的次数。 total可以在{foreach}内部,或者之后使用。

total例子:

{* 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}

{break}

{break}停止循环。

{break} 例子:

  {$data = [1,2,3,4,5]}
  {foreach $data as $value}
    {if $value == 3}
      {* abort iterating the array *}
      {break}
    {/if}
    {$value}
  {/foreach}
  {*
    prints: 1 2
  *}

{continue}

{continue}将跳过当前本次循环并进入下一次循环。

{continue} 例子:

  {$data = [1,2,3,4,5]}
  {foreach $data as $value}
    {if $value == 3}
      {* skip this iteration *}
      {continue}
    {/if}
    {$value}
  {/foreach}
  {*
    prints: 1 2 4 5
  *}

{function}

{function}用于在模板内创建函数,这些函数可以像插件函数一样调用。 用这个方式来代替写插件来显示内容,更具有可管理性。 这也可以简化数据的复杂度,如多层结构的菜单。

Note

模板函数是全局的。因为Smarty的编译器是单次编译的,所以必须用 {call} 标签来调用定义在当前模板的函数。 或者你可以直接使用函数,如{funcname ...}。

{function}标签必须设置name属性, 也就是模板函数的名称。 该名称可以用于调用模板函数。

可以按属性的方式传递给模板函数变量默认值。 和PHP函数定义一样,你只可以使用标量值作为默认。 默认值可以被覆盖,当模板函数被调用的时候。

你可以在调用模板函数内使用当前模板的全部变量,在模板内创建或修改的变量就不能被模板函数内访问了。

属性:

参数名称 类型 必选参数 默认值 说明
name string yes n/a 模板函数的名称


当模板函数被调用时,你可以传递任意数量的参数给它。除非你需要默认值,否则不要在 {funcname ...}标签内定义参数。 默认值必须是标量而且不是变量,变量必须在函数调用时才能传递。

递归菜单 {function} 例子:

{* define the function *}
{function name=menu level=0}
{function menu level=0}          {* short-hand *}
  <ul class="level{$level}">
  {foreach $data as $entry}
    {if is_array($entry)}
      <li>{$entry@key}</li>
      {menu data=$entry level=$level+1}
    {else}
      <li>{$entry}</li>
    {/if}
  {/foreach}
  </ul>
{/function}

{* create an array to demonstrate *}
{$menu = ['item1','item2','item3' => ['item3-1','item3-2','item3-3' =>
['item3-3-1','item3-3-2']],'item4']}

{* run the array through the function *}
{menu data=$menu}

  
输出:
* item1
* item2
* item3
      o item3-1
      o item3-2
      o item3-3
            + item3-3-1
            + item3-3-2
* item4
 

{if},{elseif},{else}

Smarty的{if}条件判断和PHP的if 非常相似,只是增加了一些特性。 每个{if}必须有一个配对的{/if}. 也可以使用{else} 和 {elseif}. 全部的PHP条件表达式和函数都可以在if内使用,如||, or, &&, and, is_array(), 等等.

如果开启了安全机制,那么只有在$php_functions设置允许的PHP函数才能使用。

下面是可用的运算符列表,使用中都会放到元素的中间并且用空格分隔。 注意列表中[方括号]的是可选的,而且还会列出对应PHP的表达式。

运算符 别名 语法示例 含义 对应PHP语法

==	eq	$a eq $b	等于	==
!=	ne, neq	$a neq $b	不等于	!=
>	gt	$a gt $b	大于	>
<	lt	$a lt $b	小于	<
>=	gte, ge	$a ge $b	大于等于	>=
<=	lte, le	$a le $b	小于等于	<=
===	 	$a === 0	绝对等于	===
!	not	not $a	非 (一元运算)	!
%	mod	$a mod $b	取模	%
is [not] div by	 	$a is not div by 4	取模为0	$a % $b == 0
is [not] even	 	$a is not even	[非] 取模为0 (一元运算)	$a % 2 == 0
is [not] even by	 	$a is not even by $b	水平分组 [非] 平均	($a / $b) % 2 == 0
is [not] odd	 	$a is not odd	[非] 奇数 (一元运算)	$a % 2 != 0
is [not] odd by	 	$a is not odd by $b	[非] 奇数分组	($a / $b) % 2 != 0

{if} 表达式:

{if $name eq 'Fred'}
    Welcome Sir.
{elseif $name eq 'Wilma'}
    Welcome Ma'am.
{else}
    Welcome, whatever you are.
{/if}

{* an example with "or" logic *}
{if $name eq 'Fred' or $name eq 'Wilma'}
   ...
{/if}

{* same as above *}
{if $name == 'Fred' || $name == 'Wilma'}
   ...
{/if}


{* parenthesis are allowed *}
{if ( $amount < 0 or $amount > 1000 ) and $volume >= #minVolAmt#}
   ...
{/if}


{* you can also embed php function calls *}
{if count($var) gt 0}
   ...
{/if}

{* check for array. *}
{if is_array($foo) }
   .....
{/if}

{* check for not null. *}
{if isset($foo) }
   .....
{/if}


{* test if values are even or odd *}
{if $var is even}
   ...
{/if}
{if $var is odd}
   ...
{/if}
{if $var is not odd}
   ...
{/if}


{* test if var is divisible by 4 *}
{if $var is div by 4}
   ...
{/if}


{*
  test if var is even, grouped by two. i.e.,
  0=even, 1=even, 2=odd, 3=odd, 4=even, 5=even, etc.
*}
{if $var is even by 2}
   ...
{/if}

{* 0=even, 1=even, 2=even, 3=odd, 4=odd, 5=odd, etc. *}
{if $var is even by 3}
   ...
{/if}

{if} 的更多例子:

{if isset($name) && $name == 'Blog'}
     {* do something *}
{elseif $name == $foo}
    {* do something *}
{/if}

{if is_array($foo) && count($foo) > 0}
    {* do a foreach loop *}
{/if}
 

{include}

{include}用于载入其他模板到当前模板中。 在包含模板中可用的变量,载入后在当前模板仍然可用。

{include}必须设置file 属性,设置载入的文件资源路径。

设置了可选的assign属性,将{include}模板的内容赋值到变量,而并非输出。 与 {assign}操作相似。

包含模板时,可以像使用属性一样设置传递的变量。 这样传递的变量,作用范围仅限于包含的模板内。 属性传递的变量将覆盖原包含模板的同名变量。

你可以在当前模板内使用包含模板的全部变量。 但是如果包含模板内有修改或者新建变量,那么这些变量只有包含模板的作用范围,而不可以是当前{include}模板中使用。 这种默认的设置,可以通过在包含模板时设置{include}的作用范围属性,或者 在修改或新增变量时通过{assign}的作用范围属性来设定。 后者在需要包含模板返回值时比较有用。

当文件不在$template_dir目录中时, 使用资源的语法来{include}包含文件。

Attributes:

参数名称 类型 必选参数 默认值 说明 file string Yes n/a 包含载入的文件名 assign string No n/a 将包含的文件内容赋值给变量 cache_lifetime integer No n/a 单独开启被包含模板的缓存时间 compile_id string/integer No n/a 单独设置被包含模板的编译ID cache_id string/integer No n/a 单独设置被包含模板的缓存ID scope string No n/a 定义被包含模板的赋值变量作用范围: 'parent','root' 或 'global' [var ...] [var type] No n/a 传递到包含模板的变量

可选标记:

名称 说明 nocache 关闭包含模板的缓存 caching 打开包含模板的缓存 inline 设置成true时,在编译时把包含模板的内容也合并到当前模板的编译文件中。

例子:

【简单 {include} 例子】
<html>
<head>
  <title>{$title}</title>
</head>
<body>
{include file='page_header.tpl'}

{* body of template goes here, the $tpl_name variable
   is replaced with a value eg 'contact.tpl'
*}
{include file="$tpl_name.tpl"}

{* using shortform file attribute *}
{include 'page_footer.tpl'}
</body>
</html>

  
【{include} 传递变量】
{include 'links.tpl' title='Newest links' links=$link_array}
{* body of template goes here *}
{include 'footer.tpl' foo='bar'}
  
包含了下面的 links.tpl 模板

<div id="box">
<h3>{$title}{/h3>
<ul>
{foreach from=$links item=l}
.. do stuff  ...
{/foreach}
</ul>
</div>


【{include} 作用范围示例】
在包含的模板内赋值的变量,在包含模板内可见。
{include 'sub_template.tpl' scope=parent}
...
{* display variables assigned in sub_template *}
{$foo}<br>
{$bar}<br>
...
  
包含了下面的 sub_template.tpl 模板

...
{assign var=foo value='something'}
{assign var=bar value='value'}
...


【{include} 关闭缓存】
包含模板将不被缓存
{include 'sub_template.tpl' nocache}
...

  
【{include} 单独的缓存时间】
下面例子包含模板将单独设置缓存时间500秒。
{include 'sub_template.tpl' cache_lifetime=500}
...
 

【{include}开启缓存】
下面的例子包含模板的缓存将独立于全局模板缓存设置之外。
{include 'sub_template.tpl' caching}
...

  
【{include} 和赋值变量】
下面的例子将nav.tpl的内容赋值给了$navbar 变量, 该变量将页面的头部和底部显示。  
<body>
  {include 'nav.tpl' assign=navbar}
  {include 'header.tpl' title='Smarty is cool'}
    {$navbar}
    {* body of template goes here *}
    {$navbar}
  {include 'footer.tpl'}
</body>

   
【{include} 相对路径】
下面的例子包含的模板文件都是相对当前模板的目录。
   {include 'template-in-a-template_dir-directory.tpl'}
   {include './template-in-same-directory.tpl'}
   {include '../template-in-parent-directory.tpl'}

    
【各种 {include} 资源例子】
{* absolute filepath *}
{include file='/usr/local/include/templates/header.tpl'}

{* absolute filepath (same thing) *}
{include file='file:/usr/local/include/templates/header.tpl'}

{* windows absolute filepath (MUST use "file:" prefix) *}
{include file='file:C:/www/pub/templates/header.tpl'}

{* include from template resource named "db" *}
{include file='db:header.tpl'}

{* include a $variable template - eg $module = 'contacts' *}
{include file="$module.tpl"}

{* wont work as its single quotes ie no variable substitution *}
{include file='$module.tpl'}

{* include a multi $variable template - eg amber/links.view.tpl *}
{include file="$style_dir/$module.$view.tpl"}
 

{ldelim},{rdelim}

{ldelim} 和 {rdelim}用于 避免解析模板定界符, 默认是 { and }。 同时你也可以用{literal}{/literal}来避免解析区域的字符,如javascript或者css。

例子:

{* this will print literal delimiters out of the template *}
{ldelim}funcname{rdelim} is how functions look in Smarty!
   
输出:

{funcname} is how functions look in Smarty!


{literal},{literal}

{literal}可以让一个模板区域的字符原样输出。 这经常用于保护页面上的Javascript或css样式表,避免因为Smarty的定界符{语法}而错被解析。 在{literal}{/literal}内的任何标签都不会被解析,原样输出。 所以如果你有需要放到{literal}内的标签,首先可以考虑是否用 {ldelim}{rdelim} 来代替定界符在页面上的显示(不用{literal})。

Note

因为Smarty会忽略那些带空格的定界符,所以通常不需要使用{literal}{/literal},。 请确定你的Javascript或者CSS样式表的大括号周围是有空格的。这是Smarty 3的新特性。

例子:

<script>
   // the following braces are ignored by Smarty
   // since they are surrounded by whitespace
   function myFoo {
     alert('Foo!');
   }
   // this one will need literal escapement
   {literal}
     function myBar {alert('This is {literal}!');}
   {/literal}
</script>
 

{nocache}

  • 微窗未开启缓存,此标签用处不大

{nocache}用于关闭模板区块的缓存。 {nocache}都必须和一个{/nocache}匹配。

Note

请确认任何一个在不缓存区域内的变量,都可以在缓存时从PHP获取到值。

例子:

Today's date is
{nocache}
{$smarty.now|date_format}
{/nocache}
 

{section},{sectionelse}

{section}可以循环遍历 连续数字索引的数组, 区别于{foreach} 可以循环任意关联数组. 每个{section}标签都必须有一个匹配的{/section}关闭标签。

Note

{foreach} 可以做到任何{section}做到的功能, 而且更简单和有更清晰的语法。一般更推荐使用{foreach}语法.

Note

{section}不能用于循环关联数组,它仅能循环数字索引的、连续下标的 (0,1,2,...)数组。 要循环关联数组,请使用{foreach}。

参数名称	类型	必选参数	默认值	说明
name	string	Yes	n/a	section的名称
loop	mixed	Yes	n/a	用于循环的值
start	integer	No	0	设置开始循环的下标。如果设置成负值,则会从数组的结束位置开始。 比如说,如果数组中有7个元素,设置该值为-2,则循环将从下标5开始。 设置了不正确的值(比如说在数组长度以外的值)那么会自动计算为最接近的值。
step	integer	No	1	循环的步长值。比如,step=2将循环下标0,2,4,等。 如果step值设置成负数,那么将从最后开始计算步长。
max	integer	No	n/a	设置最大的循环次数。
show	boolean	No	TRUE	是否显示循环内容

可选标记:

名称 说明 nocache 关闭{section}缓存 name 和 loop是必须的参数。

{section}的name可以是任意字符,如数字、字母或下划线等,和 PHP 变量一样的命名规则。

{section}可以嵌套,而且嵌套的{section}名称必须唯一。

loop一般是数组,决定了{section}的循环次数。 同时你也可以传递一个整数指定循环次数。

当在{section}内显示变量时, {section} 的name必须给变量名称加上[方括号].

如果loop属性为空,{sectionelse}将执行。

{section}同时还有自己的属性。 这些属性都是通过: {$smarty.section.name.property}来使用,其中“name”是name属性.

{section}的内置属性有: index, index_prev, index_next, iteration, first, last, rownum, loop, show, total.


【简单的{section}例子】

assign()赋值一个数组

<?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 />


【{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


【给{section}设置名称】

{section}的 name属性可以是任意字符,请参见PHP 变量定义. 它是用于引用{section}的数据.

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


【{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>


【{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>


【{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', '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 />


【{sectionelse}的数据库例子】

数据库查找的结果(如 ADODB 或 PEAR) 传递到 Smarty

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

模板将以表格形式显示数据结果

<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

index是当前数组的索引值,从0开始,或者从设定的start值开始。它将每次循环增加1或者增加指定的step值。

Note

如果 step 和 start都没有被指定, 那么它会和iteration属性很像, 只不过它是从0开始,而iteration是从1开始.

{section} index 属性


Note

$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属性值。

index, index_next 和 index_prev 属性

<?php
$data = array(1001,1002,1003,1004,1005);
$this->cs->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>


.iteration

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

Note

它和index不同,不会受到{section} 的属性 start, step 和 max等影响. 而且和index不同的是,iteration还是从1开始计算的。 rownum是 iteration的别名,它们是一样的。

iteration属性

<?php
// array of 3000 to 3015
$id = range(3000,3015);
$this->cs->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>

Note

"is div by"语法是PHP取模运算的一个变种。取模运算{if $smarty.section.co.iteration % 5 == 1}也是可用的。

Note

你还可以用"is odd by"来反转交替。

.first

如果当前的循环是第一次,first将被设成 TRUE 。

.last

如果当前的循环是最后一次,那么last将为 TRUE。

{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

rownum是当前循环的次数,从1开始。它是iteration 的别名。

.loop

loop 是最后一次{section}循环的下标。 它可以在{section}循环中或者循环后使用。

{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是一个布尔值参数。如果设置为FALSE,section将不会被显示。 如果有{sectionelse}显示,它们将被交替显示。

show 属性

布尔值 $show_customer_info 可以在PHP程序赋值并传递到模板中, 可以控制section的显示与否。

{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}循环中或者循环后使用。

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.

{setfilter}

{setfilter}...{/setfilter}块标签可以使用模板定义的变量过滤器。

语法: {setfilter filter1|filter2|filter3....}...{/setfilter}

过滤器可以是:

  1. 变量过滤插件的名称。
  2. 修饰器的名称和可选的参数。

{setfilter}...{/setfilter}可以被嵌套。 内部的过滤器块会被外部的过滤器块给替代。

模板过滤器可以和其他过滤器修饰器一起使用。 它们会按照如下顺序执行: 修饰器, 默认修饰器, $escape_html, 注册的变量过滤器, 自动载入的变量过滤器, 模板块变量过滤器。 所有在“默认修饰器”之后的东西,都可以被nofilter关闭。

例子:

<script>
{setfilter filter1}
  {$foo} {* filter1 runs on output of $foo *}
  {setfilter filter2|mod:true}
    {$bar} {* filter2 and modifier mod runs on output of $bar *}
  {/setfilter}
  {$buh} {* filter1 runs on output of $buh *}
{/setfilter}
{$blar} {* no template instance filter runs on output of $blar}
</script>

Note

模板块变量过滤器不会影响到包含的子模板。


{strip} 很多时候,页面设计师会遇到模板上的空格和回车影响到页面输出HTML的情况(浏览器“特性”), 所以你可以把你的标签都放到一起,以取得想要的结果。但这很容易最终导致模板无法阅读和管理。

任何在{strip}{/strip}中的标签都会被过滤掉多余的空格和回车, 并把全部标签放在同一行内显示。 这样你的模板还是可读的,而且也不需要担心多余的空格问题。

Note

{strip}{/strip}不会作用于变量的内容, 需要使用strip 修饰器来过滤变量内容。

例子:

{* the following will be all run into one line upon output *}
{strip}
<table border='0'>
 <tr>
  <td>
   <a href="{$url}">
    <font color="red">This is a test</font>
   </a>
  </td>
 </tr>
</table>
{/strip}

输出:

<table border='0'><tr><td><a href="http://. snipped...</a></td></tr></table>

注意上面的例子,在一行内显示了全部的HTML标签,而且是全部文字都会放到一起。 如果你有要原样输出的多行文字,那么它们也会变成一行显示。

{while} Smarty的{while}循环和PHP的while 在灵活性方面是几乎一样的,只是增加了少许特性。 每个{while}必须有相应的{/while}. 任何的PHP条件或者函数表达式都是可用的,如||, or, &&, and, is_array(), 等等.

下面是可用的运算符列表,使用中都会放到元素的中间并且用空格分隔。 注意列表中[方括号]的是可选的,而且还会列出对应PHP的表达式。

运算符 别名 语法示例 含义/th> 对应PHP语法
== eq $a eq $b 等于 ==
 != ne, neq $a neq $b 不等于  !=
> gt $a gt $b 大于 >
< lt $a gt $b 小于 <
>= gte,ge $a ge $b 大于等于 >=
><= lte,le $a le $b 大于等于 ><=
>=== $a === 0 绝对等于 >===
>! not not $a 非 (一元运算) >!
>% mot $a mod $b 取模 >%
is [not] div by	 	$a is not div by 4	取模为0	$a % $b == 0
is [not] even	 	$a is not even	[非] 取模为0 (一元运算)	$a % 2 == 0
is [not] even by	 	$a is not even by $b	水平分组 [非] 平均	($a / $b) % 2 == 0
is [not] odd	 	$a is not odd	[非] 奇数 (一元运算)	$a % 2 != 0
is [not] odd by	 	$a is not odd by $b	[非] 奇数分组	($a / $b) % 2 != 0

例子:

{while $foo > 0}
  {$foo--}
{/while}
  • 例子将从$foo开始计算到1

参见 {foreach}, {for} 和 {section}.