Smarty是一个使用PHP写出来的模板引擎,是目前业界最著名的PHP模板引擎之一。它分离了逻辑代码和外在的内容,提供了一种易于管理和使用的方法,用来将本来与HTML代码混杂在一块儿PHP代码逻辑分离。简单的讲,目的就是要使PHP程序员同前端人员分离,使程序员改变程序的逻辑内容不会影响到前端人员的页面设计,前端人员从新修改页面不会影响到程序的程序逻辑,这在多人合做的项目中显的尤其重要。做为一个前端工程师了解Smarty也颇有必要,本文是从官方文档上概括出来的简明教程,以备快速查阅。javascript
全部的smarty模板标签都被加上了定界符。默认状况下是 { 和},但它们是可被改变的,能够进行自定义设置。php
示例:css
{* Smarty *}
每个smarty标签输出一个变量或者调用某种函数。在定界符内 函数(用'{'包住)和其属性(用界符包住)将被处理和输出。html
示例:前端
{config_load file="colors.conf"} {include file="header.tpl"} {if $highlight_name} Welcome, <font color="{#fontColor#}">{$name}!</font> {else} Welcome, {$name}! {/if} {include file="footer.tpl"}
大多数函数都带有本身的属性以便于明确说明或者修改他们的行为。smarty函数的属性很像HTML中的属性。静态数值不须要加引号,可是字符串建议使用引号。 若是用变量做属性,它们也不能加引号。java
示例:ios
{include file="header.tpl"} {include file=$includeFile} {include file=#includeFile#} {html_select_date display_days=yes} <SELECT name=company> {html_options values=$vals selected=$selected output=$output} </SELECT>
Smarty能够识别嵌入在双引号中的变量,只要此变量只包含数字、字母、下划线和中括号[]。对于其余的符号(句号、对象相关的,等等)此变量必须用两个'`'(此符号和‘ ~ '在同一个键上,通常在ESC键下面一个键上)包住。程序员
SYNTAX EXAMPLES: {func var="test $foo test"} <-- sees $foo {func var="test $foo_bar test"} <-- sees $foo_bar {func var="test `$foo.bar` test"} <-- sees $foo.bar PRACTICAL EXAMPLES: {include file="subdir/$tpl_name.tpl"} <-- will replace $tpl_name with value {cycle values="one,two,`$smarty.config.myval`"} <-- must have backticks
数学运算能够直接应用到变量。web
{$foo+1} {$foo*$bar} {$foo->bar-$bar[1]*$baz->foo->bar()-3*7} {$foo|truncate:"`$fooTruncCount/$barTruncFactor-1`"} {assign var="foo" value="`$foo+$bar`"}
在Smarty模版,若是‘{’和‘}’大括号里包含有空格那么整个{}内容会被忽略,你能够设置Smarty类变量$auto_literal=false来取消这种规则。正则表达式
{literal}...{/literal}块被用来忽略模版语法的解析,你也能够用{ldelim}、{rdelim}标签或{$smarty.ldelim}、{$smarty.rdelim}变量来忽略个别大括号(译注:后面两种方法主要用来在模版中输出左右大括号)。
Smarty默认定界符‘{’和‘}’简洁地描述具体的内容,然而若是你有更好的定界符设置,也能够用Smarty的$left_delimiter和$right_delimiter设置相应的值。
调用从PHP分配的变量需在前加"$"符号,调用模板内的assign函数分配的变量也是这样。
要想引用关联数组变量,能够用'.'取得对应key的value。
{$Smarty.example}
能够经过变量的下标取得对应的位置的元素。
{$Smarty[index]}
对象的属性能够经过“->”符号引用。
{$Smarty->key}
你能够选择为主要的Smarty对象做用域分配变量,createData()用来创建数据对象,createTemplate()用来创建模板对象。这些对象支持链式,在模板中能够查看全部模板自己的对象变量和全部分配给父对象链的变量。默认状况下,模板在执行$smarty->displaty(...)、$smarty->fetch(...)方法时已自动连接至Smarty对象变量范围。对于分配到单个数据或模板对象的变量,您能够彻底控制哪些变量在模板中可见。
// 为Smarty对象域分配变量 $smarty->assign('foo','smarty'); // 为数据对象域分配变量 $data = $smarty->createData(); $data->assign('foo','data'); $data->assign('bar','bar-data'); // 为其它数据对象域分配变量 $data2 = $smarty->createData($data); $data2->assign('bar','bar-data2'); // 为模版对象域分配变量 $tpl = $smarty->createTemplate('index.tpl'); $tpl->assign('bar','bar-template');
配置文件中的变量须要经过用两个"#"或者是smarty的保留变量"$smarty.config."来调用。配置文件的变量只有在它们被加载之后才能使用。
示例:
foo.conf: pageTitle = "This is mine" bodyBgColor = "#eeeeee" tableBorderSize = "3" tableBgColor = "#bbbbbb" rowBgColor = "#cccccc" index.tpl: {config_load file="foo.conf"} <html> <title>{#pageTitle#}</title> <body bgcolor="{#bodyBgColor#}"> <table border="{#tableBorderSize#}" bgcolor="{#tableBgColor#}"> <tr bgcolor="{#rowBgColor#}"> <td>First</td> <td>Last</td> <td>Address</td> </tr> </table> </body> </html>
变量调节器用于变量,自定义函数和字符串。 请使用‘|’符号和调节器名称应用调节器。 变量调节器由赋予的参数值决定其行为。 参数由‘:’符号分开。
示例:
{* Uppercase the title *} <h2>{$title|upper}</h2> {* Truncate the topic to 40 characters use ... at the end *} Topic: {$topic|truncate:40:"..."} {* format a literal string *} {"now"|date_format:"%Y/%m/%d"} {* apply modifier to a custom function *} {mailto|upper address="me@domain.dom"}
对于同一个变量,你可使用多个修改器。它们将从左到右按照设定好的顺序被依次组合使用。使用时必需要用"|"字符做为它们之间的分隔符。
示例:
{$Smarty|lower|spacify|truncate:30:". . ."}
这是{assign}函数的简写版,你能够直接赋值给模版,也能够为数组元素赋值。
{append}用于在模板执行期间创建或追加模板变量数组。
属性:
选项标签:
示例:
{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 *}
{assign}用来在模板运行时为模板变量赋值。
属性:
选项标签:
{assign var="name" value="Bob" nocache} {assign "name" "Bob" nocache} {* short-hand *}
{block}用来定义一个命名的模板继承源区域。{block}的一个子模板源区将取代父模板中的相应区域。任意的子、父模板{block}区域能够彼此结合。能够利用子{block}定义中的append、prepend选项标记追加或预置父{block}内容。使用{$smarty.block.parent}可将父模板的{block}内容插入至子{block}内容中的任何位置。使用{$smarty.block.child}可将子模板{block}内容插入至父{block}内容中的任何位置。{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} The result would look like <html> <head> <title>Title - Page Title</title> </head> </html>
{call}用来调用{function}标签订义的模板函数,相似于插件函数。
另外你能够在模板中直接使用{funcname...}函数。
属性:
选项标签:
示例:
{* 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 *}
{capture}用来捕获模板输出的数据并将其存储到一个变量里,而不是将它们输出到页面。任何在{capture name="foo"}和{/capture}之间的数据将被存储到变量$foo中,该变量由name属性指定。
属性:
选项标签:
注:当捕获{insert}输出时要很是当心!若是你开启了$caching缓存,但愿在缓存内容里运行{insert}命令。那么,请不要捕获{insert}里面的内容!由于{insert}内容老是不被缓存。
示例:
{* 咱们不想输出一个div标签,除非包含的内容是没法显示的 *} {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}
属性:
{debug}跳转到调试控制页面。无论php脚本中如何设置debug,它都会工做,由于它在运行时就执行,它只可以显示分配的变量值;而不是(显示)正在使用的模版。然而,你能够看到变量做用域内的全部变量值。
若是cacheing设置为true,页面从缓存{debug}中加载,那么你只能看到缓存过的变量。
{extends}标签用在模板继承中子模版对父模板的继承。
示例:
{extends file='parent.tpl'} {extends 'parent.tpl'} {* short-hand *}
{for}、{forelse}标签用来建立一个简单循环,支持如下不一样的格式:
当循环无迭代时执行{forelse}。
示例:
<?php $smarty->assign('to',10); ?> <ul> {for $foo=3 to $to max=3} <li>{$foo}</li> {/for} </ul> The above example will output: <ul> <li>3</li> <li>4</li> <li>5</li> </ul>
{foreach}用来遍历数据数组,{foreach}与{section}循环相比更简单、语法更干净,也能够用来遍历关联数组。
{foreach $arrayvar as $itemvar}
{foreach $arrayvar as $keyvar=>$itemvar}
示例:
<?php $people = array('fname' => 'John', 'lname' => 'Doe', 'email' => 'j.doe@example.com'); $smarty->assign('myPeople', $people); ?> Template to output $myArray as key/value pairs. //键值对 <ul> {foreach $myPeople as $value} <li>{$value@key}: {$value}</li> {/foreach} </ul>
示例:
{foreach $myNames as $name} {if $name@iteration is div by 4} <b>{$name}</b> {/if} {$name} {/foreach}
{function}用来在模板中建立函数,能够像调用插件函数同样调用它们。取代在插件中写表象内容的函数,让模板保持一致性一般是个更好的选择。它也简化了对数据的遍历,例如深度的嵌套菜单。另外你能够在模板中直接使用{funcname...}函数。
示例:
{* 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}
随着一些特性加入到模版引擎,Smarty的{if}语句与php的if语句同样富有弹性。每个{if}必须与一个{/if}成对出现,容许使用{else}和{elseif},全部php条件和函数在这里一样适用,诸如||、or、&&、and、is_array()等等。若是开启安全,只支持符合$php_functions的安全策略属性的php函数。
下面是一串有效的限定符,它们的左右必须用空格分隔开,注意列出的清单中方括号是可选的,在适用状况下使用相应的等号(全等或不全等)。
示例:
{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 'links.tpl' title='Newest links' links=$link_array} {* body of template goes here *} {include 'footer.tpl' foo='bar'} The template above includes the example links.tpl below <div id="box"> <h3>{$title}{/h3> <ul> {foreach from=$links item=l} .. do stuff填充 ... </foreach} </ul> </div>
{include_php}在Smarty新版本中已被废弃,可以使用插件恰当地解决从(php)代码分离html的问题。
{insert}标签相似于{include}标签,不一样之处是即便打开caching,{insert}所包含的内容也不会被缓存,每次调用模板都会执行{insert}。
示例:
banner.conf: alt = come from baidu! src = xxx.com/2351.gif href = www.xxx.com main.tpl: {config_load file='banner.conf'} {insert name="getBanner" lid=#title#} test.php: include_once('../libs/Smarty.class.php'); $smarty = new Smarty; function insert_getBanner($arr,$smarty){ echo '<div><a href="'.$arr['href'].'"><img src='.$arr['src'].' alt='.$arr['alt'].'</div>'; } $smarty->display('main.tpl');
{ldelim}和{rdelim}用来转义模版定界符,默认值为“{”和“}”。你也能够用{literal}{/literal}转义文本块,例如javascript或css。
{ldelim}、{rdelim}用来输出左右delim的原义,即输出$smarty.ldelim和$smarty.rdelim的字面值。当使用{literal}{/literal}成对使用时,Smarty将忽略解释里面的代码,而按原字符输出。
示例:
<script language="JavaScript" type="text/javascript"> function myJsFunction(){ldelim} alert("The server name\n{$smarty.server.SERVER_NAME}\n{$smarty.server.SERV {rdelim} </script> <a href="javascript:myJsFunction()">Click here for Server Info</a>
{literal}标签区域内的数据将按字面意思处理,表明性地是用在javascript/css语块周围,否则这些语言使用的花括号‘{’、‘}’会干扰模版定界符语法。{literal}{/literal}标签里面的全部符号不会被解释,所有按原样输出。若是有须要在{literal}块里使用模版标签,能够考虑使用{ldelim}{rdelim}转义单独的分隔符。
{nocache}用来禁止模版块缓存,每一个{nocache}应与{/nocache}成对出现。当从缓存中加载页面时应肯定无缓存块使用的变量为php变量(而非模板中定义的变量)。
示例:
Today's date is
{nocache}
{$smarty.now|date_format}
{/nocache}
{php}已被Smarty弃用,不该再使用。仍是用你本身编写的php脚本或插件函数来代替它吧!
不一样于{foreach}遍历单层关联数组,{section}支持循序索引遍历数组中的数据(支持一次性读取多维数组)。每一个{section}标签必须与闭合标签{/section}成对出现。
注:{foreach}能够作{section}能作的全部事,并且语法更简单、更容易。它一般是循环数组的首选。{section}循环不能遍历关联数组,(被循环的)数组必须是数字索引,像这样(0,1,2,...)。对于关联数组,请用{foreach}循环。
属性:
选项标签:
随着一些特性加入到模版引擎,Smarty的{while}循环与php的while语句同样富有弹性。每个{while}必须与一个{/while}成对出现,全部php条件和函数在它身上一样适用,诸如||、or、&&、and、is_array()等等。
下面是一串有效的限定符,它们的左右必须用空格分隔开,注意列出的清单中方括号是可选的,在适用状况下使用相应的等号(全等或不全等)。
示例:
{while $foo > 0} {$foo--} {/while}
用于输出一个记数过程。{counter}保存了每次记数时的当前记数值。用户能够经过调节间隔(skip)和方向(direction)计算该值。也能够决定是否输出该值。若是须要同时运行多个计数器,必须为它们指定不一样的名称。若是没有指定名称,模板引擎使用 "default" 做为缺省值。
若是指定了 "assign" 这个属性,该计数器的输出值将被赋给由assign指定的模板变量,而不是直接输出。
属性:
示例:
{* initialize the count *} {counter start=0 skip=2}<br /> {counter}<br /> {counter}<br /> {counter}<br />
Cycle用于交替使用一组值。该特性使得在表格中交替输出多种颜色或循环使用数组中的值变得更容易。
属性:
示例:
{section name=rows loop=$data} <tr class="{cycle values="odd,even"}"> <td>{$data[rows]}</td> </tr> {/section} The above template would output: <tr class="odd"> <td>1</td> </tr> <tr class="even"> <td>2</td> </tr> <tr class="odd"> <td>3</td> </tr>
将变量做为一个模板求值。该特性用于诸如将模板标签/变量嵌入至另外一变量,或将标签/变量嵌入至配置文件中的变量的情形。若是指定了assign这个属性,{eval}函数的输出内容将被赋给由assign指定的模板变量,而不是直接输出。
属性:
示例:
The contents of the config file, setup.conf. 配置文件 emphstart = <strong> emphend = </strong> title = Welcome to {$company}'s home page! ErrorCity = You must supply a {#emphstart#}city{#emphend#}. ErrorState = You must supply a {#emphstart#}state{#emphend#}. Where the template is: 模板 {config_load file='setup.conf'} {eval var=$foo} {eval var=#title#} {eval var=#ErrorCity#} {eval var=#ErrorState# assign='state_error'} {$state_error}
用于从本地文件系统、HTTP或FTP上检索文件并显示其内容。
注:{fetch}不支持重定向,使用前请肯定但愿抓取的网页地址以'/'结尾!若是开启了安全设置,当取本地文件时{fetch}只能取位于$decure_dir路径定义的安全文件夹下的资料。
属性:
示例:
{* include some javascript in your template *} {fetch file='/export/httpd/www.example.com/docs/navbar.js'} {* embed some weather text in your template from another web site *} {fetch file='http://www.myweather.com/68502/'} {* fetch a news headline file via ftp *} {fetch file='ftp://user:password@ftp.example.com/path/to/currentheadlines.txt'} {* as above but with variables *} {fetch file="ftp://`$user`:`$password`@`$server`/`$path`"} {* assign the fetched contents to a template variable *} {fetch file='http://www.myweather.com/68502/' assign='weather'} {if $weather ne ''} <div id="weather">{$weather}</div> {/if}
自定义函数{html_checkboxes}根据给定的数据建立复选按钮组。该函数能够指定哪些元素被选定。
属性:
示例:
<?php $smarty->assign('cust_ids', array(1000,1001,1002,1003)); $smarty->assign('cust_names', array( 'Joe Schmoe', 'Jack Smith', 'Jane Johnson', 'Charlie Brown') ); $smarty->assign('customer_id', 1001); ?> where template is {html_checkboxes name='id' values=$cust_ids output=$cust_names selected=$customer_id separator='<br />'}
自定义函数{html_image}产生一个图象的HTML标签。若是没有提供高度和宽度值,将根据图象的实际大小自动取得。
属性:
自定义函数{html_options}根据给定的数据建立<select><option>选项组。它会留意哪一个选项在默认状况下被选中。
属性:
自定义函数{html_radios}根据给定的数据建立html单选按钮组,该函数能够指定哪一个元素被选定。
属性:
自定义函数{html_select_date}用于建立日期下拉列表,它能够显示任意年月日。下述列表中没有说明的参数会在相应的年、月、日<select>标签中以名/值的键值对形式显示出来。
属性:
自定义函数{html_select_time}用于建立时间下拉菜单,它能够显示任意时、分、秒和正午界。此时间属性能够有不一样的形式,能够是一个独特的时间戳,也能够是YYYYMMDDHHMMSS(年月日时分秒毫秒)形式,或者php的strtotime()解析的字符串形式。
属性:
自定义函数{html_table}将数组中的数据填充到HTML表格中。
属性:
{mailto}自动生成电子邮件连接,并根据选项决定是否对地址信息进行编码。经编码后的email将使网络蜘蛛破解邮件地址变得更困难。
属性:
示例:
{mailto address="me@example.com"} <a href="mailto:me@example.com" >me@example.com</a> {mailto address="me@example.com" text="send me some mail"} <a href="mailto:me@example.com" >send me some mail</a> {mailto address="me@example.com" encode="javascript"} <script type="text/javascript" language="javascript"> eval(unescape('%64%6f% ... snipped ...%61%3e%27%29%3b')) </script> {mailto address="me@example.com" encode="hex"} <a href="mailto:%6d%65.. snipped..3%6f%6d">m&..snipped...#x6f;m</a> {mailto address="me@example.com" subject="Hello to you!"} <a href="mailto:me@example.com?subject=Hello%20to%20you%21" >me@example.com</a> {mailto address="me@example.com" cc="you@example.com,they@example.com"} <a href="mailto:me@example.com?cc=you@example.com%2Cthey@example.com" >me@example. {mailto address="me@example.com" extra='class="email"'} <a href="mailto:me@example.com" class="email">me@example.com</a> {mailto address="me@example.com" encode="javascript_charcode"} <script type="text/javascript" language="javascript"> <!-- {document.write(String.fromCharCode(60,97, ... snipped ....60,47,97,62))} //--> </script>
{math}容许模板设计者在模板中进行数学表达式运算。
注:因为使用了php的eval()函数,{math}函数的代价昂贵(性能较低),在PHP中作数学运算效率会更高一些,所以要尽量在PHP中作数学运算,将结果赋给模板变量。在相似{section}这样的循环中,应尽可能避免反复调用{math}函数。
属性:
示例:
{* $row_height = 10, $row_width = 20, #col_div# = 2, assigned in template *} {math equation="height * width / division" height=$row_height width=$row_width division=#col_div#} The above example will output: 100
{textformat}用于格式化文本。该函数主要清理空格和特殊字符,对段落按单词边界换行和行缩进等段落格式化处理。用户能够明确设置参数,或使用预处理风格。目前只有惟一可用风格"email"。
属性: