前面的话
对PHP来说,有很多模板引擎可供选择,但Smarty是一个使用PHP编写出来的,是业界最著名、功能最强大的一种PHP模板引擎。Smarty像PHP一样拥有丰富的函数库,从统计字数到自动缩进、文字环绕以及正则表达式都可以直接使用,如果觉得不够,SMARTY还有很强的扩展能力,可以通过插件的形式进行扩充。另外,Smarty也是一种自由软件,用户可以自由使用、修改,以及重新分发该软件。本文将详细介绍Smarty模板引擎
概述
Smarty是一个php模板引擎。更准确的说,它分离了逻辑程序和外在的内容,提供了一种易于管理的方法。Smarty总的设计理念就是分离业务逻辑和表现逻辑,优点概括如下:
速度——相对于其他的模板引擎技术而言,采用Smarty编写的程序可以获得最大速度的提高
编译型——采用Smarty编写的程序在运行时要编译成一个非模板技术的PHP文件,这个文件采用了PHP与HTML混合的方式,在下一次访问模板时将Web请求直接转换到这个文件中,而不再进行模板重新编译(在源程序没有改动的情况下),使用后续的调用速度更快
缓存技术——Smarty提供了一种可选择使用的缓存技术,它可以将用户最终看到的HTML文件缓存成一个静态的HTML页面。当用户开启Smarty缓存时,并在设定的时间内,将用户的Web请求直接转换到这个静态的HTML文件中来,这相当于调用一个静态的HTML文件
插件技术——Smarty模板引擎是采用PHP的面向对象技术实现,不仅可以在原代码中修改,还可以自定义一些功能插件(按规则自定义的函数)
强大的表现逻辑——在Smarty模板中能够通过条件判断以及迭代地处理数据,它实际上就是种程序设计语言,但语法简单,设计人员在不需要预备的编程知识前提下就可以很快学会
模板继承——模板的继承是Smarty3的新事物。在模板继承里,将保持模板作为独立页面而不用加载其他页面,可以操纵内容块继承它们。这使得模板更直观、更有效和易管理
当然,也有不适合使用Smarty的地方。例如,需要实时更新的内容,需要经常重新编译模板,所以这类型的程序使用Smarty会使模板处理速度变慢。另外,在小项目中也不适合使用Smarty模板,小项目因为项目简单而前端与后端兼于一人的项目,使用Smarty会在一定程度上丧失PHP开发迅速的优点
配置
【安装】
安装Smarty很简单,到Smarty官方网站下载最新的稳定版本,然后解压压缩包,在解压后的目录可以看到一个名叫libs的Smarty类库目录,直接将libs文件夹复制到程序主文件夹下即可
[注意]Smarty要求web服务器运行php4.0以上版本
libs文件夹下共包含以下6个文件
Smarty.class.php(主文件) SmartyBC.class.php(兼容其他版本Smarty) sysplugins/* (系统函数插件) plugins/* (自定义函数插件) Autoloader.php debug.tpl
【实例化】
/* 并指定了Smarty.class.php所在位置,注意‘S‘是大写的*/ require ‘./libs/Smarty.class.php‘; /* 实例化Smarty类的对象$smarty */ $smarty = new Smarty();
【init】
Smarty要求4个目录,默认下命名为:tempalates、templates_c、configs和cache。每个都是可以自定义的,可以分别修改Smarty类属性或相关方法:$template_dir、$compile_dir、$config_dir和$cache_dir
/** file: init.inc.php Smarty对象的实例化及初使化文件 */ define("ROOT", str_replace("\\", "/",dirname(__FILE__)).‘/‘); //指定项目的根路径 require ROOT.‘libs/Smarty.class.php‘; //加载Smarty类文件 $smarty = new Smarty(); //实例化Smarty类的对象$smarty /* 推荐用Smarty3以上版本方式设置默认路径,成功后返回$smarty对象本身,可连贯操作 */ $smarty ->setTemplateDir(ROOT.‘templates/‘) //设置所有模板文件存放的目录 // ->addTemplateDir(ROOT.‘templates2/‘) //可以添加多个模板目录 ->setCompileDir(ROOT.‘templates_c/‘) //设置所有编译过的模板文件存放的目录 ->addPluginsDir(ROOT.‘plugins/‘) //添加模板扩充插件存放的目录 ->setCacheDir(ROOT.‘cache/‘) //设置缓存文件存放的目录 ->setConfigDir(ROOT.‘configs‘); //设置模板配置文件存放的目录 $smarty->caching = false; //设置Smarty缓存开关功能 $smarty->cache_lifetime = 60*60*24; //设置模板缓存有效时间段的长度为1天 $smarty->left_delimiter = ‘<{‘; //设置模板语言中的左结束符 $smarty->right_delimiter = ‘}>‘; //设置模板语言中的右结束符
【demo】
<!-- main.tpl --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <{$content}> </body> </html>
<?php require ‘./init.inc.php‘; $smarty -> assign(‘content‘,‘this is content.....‘); $smarty -> display(‘main.tpl‘); ?>
基本语法
【注释】
模板注释被*星号包围,而两边的星号又被定界符包围。注释只存在于模板里面,而在输出的页面中不可见
<{* this is a comment *} >
【变量】
模板变量用美元符号$开始,可以包含数字、字母和下划线,这与php变量很像。可以引用数组的数字或非数字索引,当然也可以引用对象属性和方法
配置文件变量是一个不用美元符号$,而是用#号包围着变量(#hashmarks#),或者是一个$smarty.config形式的变量
[注意]Smarty可以识别嵌入在双引号中的变量
数学和嵌入标签 {$x+$y} // 输出x+y的和 {assign var=foo value=$x+$y} // 属性中的变量 {$foo[$x+3]} // 变量作为数组索引 {$foo={counter}+3} // 标签里面嵌套标签 {$foo="this is message {counter}"} // 引号里面使用标签 定义数组 {assign var=foo value=[1,2,3]} {assign var=foo value=[‘y‘=>‘yellow‘,‘b‘=>‘blue‘]} {assign var=foo value=[1,[9,8],3]} // 可以嵌套 短变量分配 {$foo=$bar+2} {$foo = strlen($bar)} {$foo = myfunct( ($x+$y)*3 )} // 作为函数参数 {$foo.bar=1} // 赋值给指定的数组索引 {$foo.bar.baz=1} {$foo[]=1} 点语法 {$foo.a.b.c} => $foo[‘a‘][‘b‘][‘c‘] {$foo.a.$b.c} => $foo[‘a‘][$b][‘c‘] {$foo.a.{$b+4}.c} => $foo[‘a‘][$b+4][‘c‘] {$foo.a.{$b.c}} => $foo[‘a‘][$b[‘c‘]] PHP语法 {$foo[1]} {$foo[‘bar‘]} {$foo[‘bar‘][1]} {$foo[$x+$x]} {$foo[$bar[1]]} {$foo[section_name]}
<!-- main.tpl --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <{***定义数组:10***}> <{assign var=foo value=[10,20,30]}> <{$foo[0]}><br> <{***短变量分配:0***}> <{$foo=0}> <{$foo}><br> <{***点语法:1***}> <{$test.a}><br> <{***PHP语法:1***}> <{$test[‘a‘]}><br> <{***数学运算:3***}> <{$test.a+$test.b}><br> </body> </html>
<?php require ‘./init.inc.php‘; $smarty -> assign(‘test‘,[‘a‘=>1,‘b‘=>2]); $smarty -> display(‘main.tpl‘); ?>
【函数】
每一个smarty标签输出一个变量或者调用某种函数。在定界符内函数和其属性将被处理和输出
<{funcname attr1="val" attr2="val"}>
{config_load file="colors.conf"} {include file="header.tpl"} {if $highlight_name} Welcome, <div style="color:{#fontColor#}">{$name}!</div> {else} Welcome, {$name}! {/if} {include file="footer.tpl"}
【属性】
大多数函数都带有自己的属性以便于明确说明或者修改他们的行为,smarty函数的属性很像HTML中的属性。静态数值不需要加引号,但是字符串建议使用引号。可以使用普通smarty变量,也可以使用带调节器的变量作为属性值,它们也不用加引号。甚至可以使用php函数返回值和复杂表达式作为属性值
一些属性用到了布尔值(true或false),它们表明为真或为假。如果没有为这些属性赋布尔值,那么默认使用true为其值
{include file="header.tpl"} {include file="header.tpl" nocache} // 等于nocache=true {include file="header.tpl" attrib_name="attrib value"} {include file=$includeFile} {include file=#includeFile# title="My Title"} {assign var=foo value={counter}} {assign var=foo value=substr($bar,2,5)} {assign var=foo value=$bar|strlen} {assign var=foo value=$buh+$bar|strlen} {html_select_date display_days=true} {mailto address="[email protected]"} <select name="company_id"> {html_options options=$companies selected=$company_id} </select>
变量
Smarty有几种不同类型的变量,变量的类型取决于它的前缀符号是什么(或者被什么符号包围)。Smarty的变量可以直接被输出或者作为函数属性和调节器(modifiers)的参数,或者用于内部的条件表达式等等。如果要输出一个变量,只要用定界符将它括起来就可以
1、从PHP分配的变量
index.php: $smarty = new Smarty; $smarty->assign(‘Contacts‘,array(‘fax‘ => ‘555-222-9876‘,‘email‘ => ‘[email protected]‘)); $smarty->display(‘index.tpl‘); index.tpl: <{$Contacts.fax}><br> <{$Contacts.email}><br> OUTPUT: 555-222-9876<br> [email protected].com<br>
2、从配置文件读取的变量
加载配置文件后,配置文件中的变量需要用两个井号"#"包围或者是smarty的保留变量$smarty.config.来调用
foo.conf: pageTitle = "This is mine" tableBgColor = "#bbbbbb" rowBgColor = "#cccccc" <!-- main.tpl --> <{config_load file=‘foo.conf‘}> <!DOCTYPE> <html> <title><{#pageTitle#}></title> <body> <table style="background:<{#tableBgColor#}>"> <tr style="background:<{#rowBgColor#}>"> <td>First</td> <td>Last</td> <td>Address</td> </tr> </table> </body> </html> <?php require ‘./init.inc.php‘; $smarty -> display(‘main.tpl‘); ?>
3、配置文件里分区域的变量
foo.conf: [a] x=1 [b] x=2 [c] x=3 <!-- main.tpl --> <{config_load file=‘foo.conf‘ section="a"}> <{#x#}> output: 1
4、模板里定义的变量
<{$name=‘Bob‘}> The value of $name is <{$name}>. output: The value of $name is Bob.
5、保留变量
$smarty.get $smarty.post $smarty.cookies $smarty.server $smarty.env $smarty.session $smarty.request $smarty.now //当前时间戳 $smarty.const //访问php常量 $smarty.capture //捕获内置的{capture}...{/capture}模版输出 $smarty.config //取得配置变量。{$smarty.config.foo}是{#foo#}的同义词 $smarty.section //指向{section}循环的属性 $smarty.template //返回经过处理的当前模板名 $smarty.current_dir //返回经过处理的当前模板目录名 $smarty.version //返回经过编译的Smarty模板版本号
<!-- main.tpl --> <{$smarty.now}><br> <{date(‘Y-m-d‘,$smarty.now)}><br> <{$smarty.template }><br> <{$smarty.current_dir }><br> <{$smarty.version }><br>
变量调节器
变量调节器作用于变量、自定义函数或字符串。变量调节器的用法是:‘|’符号右接调节器名称。变量调节器可接收附加参数影响其行为。参数位于调节器右边,并用‘:’符号分开
[注意]对于同一个变量,可以使用多个修改器。它们将从左到右按照设定好的顺序被依次组合使用。使用时必须要用"|"字符作为它们之间的分隔符
capitalize[首字符大写]
将变量里的所有单词首字大写,与php的ucwords()函数类似。默认参数为false用于确定带数字的单词是否需要大写
<{$articleTitle="next x-men film, x3, delayed."}> <{$articleTitle}><br> <{$articleTitle|capitalize}><br> <{$articleTitle|capitalize:true}> <br> output: next x-men film, x3, delayed. Next X-Men Film, x3, Delayed. Next X-Men Film, X3, Delayed.
lower[小写]
将变量字符串小写,作用等同于php的strtolower()函数
<{$articleTitle="Next x-men film, x3, delayed."}> <{$articleTitle}><br> <{$articleTitle|lower}><br> output: Next x-men film, x3, delayed. next x-men film, x3, delayed.
upper[大写]
将变量改为大写,等同于php的strtoupper()函数
<{$articleTitle="Next x-men film, x3, delayed."}> <{$articleTitle}><br> <{$articleTitle|upper}><br> output: Next x-men film, x3, delayed. NEXT X-MEN FILM, X3, DELAYED.
cat[连接字符串]
将cat里的值后接到给定的变量后面
<{$articleTitle="next x-men film, x3, delayed."}> <{$articleTitle|cat:" yesterday."}> OUTPUT: next x-men film, x3, delayed. yesterday.
count_characters[字符计数]
计算变量里的字符数。默认参数为false,用于确定是否计算空格字符
<{$articleTitle="next x-men film, x3, delayed."}> <{$articleTitle}><br> <{$articleTitle|count_characters}><br> <{$articleTitle|count_characters:true}><br> OUTPUT: next x-men film, x3, delayed. 25 29
count_paragraphs[计算段数]
计算变量里的段落数量
<{$articleTitle="next x-men\n film, x3, delayed."}> <{$articleTitle}><br> <{$articleTitle|count_paragraphs}><br> OUTPUT: next x-men film, x3, delayed. 2
count_sentences[计算句数]
计算变量里句子的数量
<{$articleTitle="next x-men. film, x3, delayed."}> <{$articleTitle}><br> <{$articleTitle|count_sentences}><br> OUTPUT: next x-men. film, x3, delayed. 2
count_words[计算词数]
计算变量里的词数
<{$articleTitle="next x-men film, x3, delayed."}> <{$articleTitle}><br> <{$articleTitle|count_words}><br> OUTPUT: next x-men film, x3, delayed. 5
date_format[格式化日期]
%a - 当前区域星期几的简写 %A - 当前区域星期几的全称 %b - 当前区域月份的简写 %B - 当前区域月份的全称 %c - 当前区域首选的日期时间表达 %C - 世纪值(年份除以 100 后取整,范围从 00 到 99) %d - 月份中的第几天,十进制数字(范围从 01 到 31) %D - 和 %m/%d/%y 一样 %e - 月份中的第几天,十进制数字,一位的数字前会加上一个空格(范围从 ‘ 1‘ 到 ‘31‘) %g - 和 %G 一样,但是没有世纪 %G - 4 位数的年份,符合 ISO 星期数(参见 %V)。和 %V 的格式和值一样,只除了如果 ISO 星期数属于前一年或者后一年,则使用那一年。 %h - 和 %b 一样 %H - 24 小时制的十进制小时数(范围从 00 到 23) %I - 12 小时制的十进制小时数(范围从 00 到 12) %j - 年份中的第几天,十进制数(范围从 001 到 366) %m - 十进制月份(范围从 01 到 12) %M - 十进制分钟数 %n - 换行符 %p - 根据给定的时间值为 `am‘ 或 `pm‘,或者当前区域设置中的相应字符串 %r - 用 a.m. 和 p.m. 符号的时间 %R - 24 小时符号的时间 %S - 十进制秒数 %t - 制表符 %T - 当前时间,和 %H:%M:%S 一样 %u - 星期几的十进制数表达 [1,7],1 表示星期一 %U - 本年的第几周,从第一周的第一个星期天作为第一天开始 %V - 本年第几周的 ISO 8601:1988 格式,范围从 01 到 53,第 1 周是本年第一个至少还有 4 天的星期,星期一作为每周的第一天。(用 %G 或者 %g 作为指定时间戳相应周数的年份组成。) %W - 本年的第几周数,从第一周的第一个星期一作为第一天开始 %w - 星期中的第几天,星期天为 0 %x - 当前区域首选的时间表示法,不包括时间 %X - 当前区域首选的时间表示法,不包括日期 %y - 没有世纪数的十进制年份(范围从 00 到 99) %Y - 包括世纪数的十进制年份 %Z 或 %z - 时区名或缩写 %% - 文字上的 `%‘ 字符
<{$smarty.now|date_format}><br> <{$smarty.now|date_format:"%D"}><br> output: Mar 25, 2017 03/25/17
default[默认值]
为变量设置一个默认值。当变量未设置或为空字符串时,将由给定的默认值替代其输出
<{$articleTitle|default:‘a‘}><br> <{$articleTitle="next x-men film, x3, delayed."}> <{$articleTitle|default:‘a‘}><br> output: a next x-men film, x3, delayed.
escape[转义]
escape作用于变量,用以html、url、单引号、十六进制、十六进制实体、javascript、邮件的转码或转义。第一个参数默认为‘html‘,可选参数有‘html,htmlall,url,quotes,hex,hexentity,javascript‘;第二个参数默认为‘utf-8‘,可选参数有‘ISO-8859-1,UTF-8‘...
<{$articleTitle="‘Stiff Opposition Expected to Casketless Funeral Plan‘"}> <{$articleTitle|escape}><br> <{$articleTitle|escape:‘url‘}> output: ‘Stiff Opposition Expected to Casketless Funeral Plan‘ %27Stiff%20Opposition%20Expected%20to%20Casketless%20Funeral%20Plan%27
indent[缩进]
在每行缩进字符串,默认是4个字符。对于第一个可选参数,可以指定缩进字符数,对于第二个可选参数,可以指定使用什么字符缩进,例如‘\t‘作为tab
<{$articleTitle="‘Stiff Opposition Expected to Casketless Funeral Plan‘"}> <{$articleTitle}><br> <{$articleTitle|indent}> output: ‘Stiff Opposition Expected to Casketless Funeral Plan‘ ‘Stiff Opposition Expected to Casketless Funeral Plan‘
nl2br[换行符替换成<br />]
所有的换行符将被替换成 <br />,功能同PHP中的nl2br()函数一样
<{$articleTitle="Next x-men\nfilm, x3, delayed."}> <{$articleTitle}><br> <{$articleTitle|nl2br}><br> output: Next x-men film, x3, delayed. Next x-men film, x3, delayed.
regex_replace[正则替换]
使用正则表达式在变量中搜索和替换,语法来自php的preg_replace()函数
<{$articleTitle="Next x-men\nfilm, x3, delayed."}> <{$articleTitle}><br> <{$articleTitle|regex_replace:"/[\r\t\n]/":" "}><br> output: Next x-men film, x3, delayed. Next x-men film, x3, delayed.
replace[替换]
一种在变量中进行简单的搜索和替换字符串的处理。等同于php的str_replace()函数
<{$articleTitle="Next x-men film, x3, delayed."}> <{$articleTitle}><br> <{$articleTitle|replace:"x":"y"}><br> output: Next x-men film, x3, delayed. Neyt y-men film, y3, delayed.
spacify[插空]
插空是一种在变量的字符串的每个字符之间插入空格或者其他的字符(串)的方法
<{$articleTitle="Next x-men film, x3, delayed."}> <{$articleTitle}><br> <{$articleTitle|spacify}><br> <{$articleTitle|spacify:"^"}><br> output: Next x-men film, x3, delayed. N e x t x - m e n f i l m , x 3 , d e l a y e d . N^e^x^t^ ^x^-^m^e^n^ ^f^i^l^m^,^ ^x^3^,^ ^d^e^l^a^y^e^d^.
string_format[字符串格式化]
一种格式化字符串的方法,例如格式化为十进制数等等。实际运用的是php的sprintf()函数
<{$number=23.5678}> <{$number}><br> <{$number|string_format:"%.2f"}><br> <{$number|string_format:"%d"}> output: 23.5678 23.57 23
strip[去除(多余空格)]
用一个空格或一个给定字符替换所有重复空格、换行和制表符
<{$articleTitle="Grandmother of\neight makes\t hole in one."}> <{$articleTitle}><br> <{$articleTitle|strip}><br> <{$articleTitle|strip:‘ ‘}><br> output: Grandmother of eight makes hole in one. Grandmother of eight makes hole in one. Grandmother of eight makes hole in one.
strip_tags[去除html标签]
去除<和>标签,包括在<和>之间的全部内容
<{$articleTitle="Blind Woman Gets New Kidney from Dad she Hasn‘t Seen in <b>years</b>."}> <{$articleTitle}><br> <{$articleTitle|strip_tags}><br> output: Blind Woman Gets New Kidney from Dad she Hasn‘t Seen in <b>years</b>.<br> Blind Woman Gets New Kidney from Dad she Hasn‘t Seen in years .<br>
truncate[截取]
从字符串开始处截取某长度的字符,默认是80个,也可以指定第二个参数作为追加在截取字符串后面的文本串。该追加字串被计算在截取长度中。默认情况下,smarty会截取到一个词的末尾。如果想要精确的截取多少个字符,把第三个参数改为"true";第四个参数默认设置为FALSE,表示将截取至字符串末尾,设置为TRUE则截取到中间。注意如果设了TRUE,则忽略字符边界
<{$articleTitle=‘Two Sisters Reunite after Eighteen Years at Checkout Counter.‘}> <{$articleTitle}><br> <{$articleTitle|truncate}><br> <{$articleTitle|truncate:30}><br> <{$articleTitle|truncate:30:""}><br> <{$articleTitle|truncate:30:"---"}><br> <{$articleTitle|truncate:30:"":true}><br> <{$articleTitle|truncate:30:"...":true}><br> <{$articleTitle|truncate:30:‘..‘:true:true}><br> output: Two Sisters Reunite after Eighteen Years at Checkout Counter. Two Sisters Reunite after Eighteen Years at Checkout Counter. Two Sisters Reunite after... Two Sisters Reunite after Two Sisters Reunite after--- Two Sisters Reunite after Eigh Two Sisters Reunite after E... Two Sisters Re..ckout Counter.
wordwrap[行宽约束]
可以指定段落的列宽(也就是一行多少个字符,超过这个字符数换行),默认80。第二个参数可选,指定在约束点使用什么换行符,默认为"\n"。默认情况下smarty将截取到词尾,如果想精确到设定长度的字符,请将第三个参数设为ture。本调节器等同于php的wordwrap()函数
<{$articleTitle="Blind woman gets new kidney from dad she hasn‘t seen in years."}> <{$articleTitle}><br> <{$articleTitle|wordwrap:30}><br> <{$articleTitle|wordwrap:20}><br> <{$articleTitle|wordwrap:30:"<br />\n"}><br> <{$articleTitle|wordwrap:26:"\n":true}><br> output: Blind woman gets new kidney from dad she hasn‘t seen in years.<br> Blind woman gets new kidney from dad she hasn‘t seen in years.<br> Blind woman gets new kidney from dad she hasn‘t seen in years.<br> Blind woman gets new kidney<br /> from dad she hasn‘t seen in<br /> years.<br> Blind woman gets new kidney from dad she hasn‘t seen in years.<br>