對PHP來講,有不少模板引擎可供選擇,但Smarty是一個使用PHP編寫出來的,是業界最著名、功能最強大的一種PHP模板引擎。Smarty像PHP同樣擁有豐富的函數庫,從統計字數到自動縮進、文字環繞以及正則表達式均可以直接使用,若是以爲不夠,SMARTY還有很強的擴展能力,能夠經過插件的形式進行擴充。另外,Smarty也是一種自由軟件,用戶能夠自由使用、修改,以及從新分發該軟件。本文將詳細介紹Smarty模板引擎javascript
Smarty是一個php模板引擎。更準確的說,它分離了邏輯程序和外在的內容,提供了一種易於管理的方法。Smarty總的設計理念就是分離業務邏輯和表現邏輯,優勢歸納以下:php
速度——相對於其餘的模板引擎技術而言,採用Smarty編寫的程序能夠得到最大速度的提升html
編譯型——採用Smarty編寫的程序在運行時要編譯成一個非模板技術的PHP文件,這個文件採用了PHP與HTML混合的方式,在下一次訪問模板時將Web請求直接轉換到這個文件中,而再也不進行模板從新編譯(在源程序沒有改動的狀況下),使用後續的調用速度更快前端
緩存技術——Smarty提供了一種可選擇使用的緩存技術,它能夠將用戶最終看到的HTML文件緩存成一個靜態的HTML頁面。當用戶開啓Smarty緩存時,並在設定的時間內,將用戶的Web請求直接轉換到這個靜態的HTML文件中來,這至關於調用一個靜態的HTML文件java
插件技術——Smarty模板引擎是採用PHP的面向對象技術實現,不只能夠在原代碼中修改,還能夠自定義一些功能插件(按規則自定義的函數)web
強大的表現邏輯——在Smarty模板中可以經過條件判斷以及迭代地處理數據,它實際上就是種程序設計語言,但語法簡單,設計人員在不須要預備的編程知識前提下就能夠很快學會正則表達式
模板繼承——模板的繼承是Smarty3的新事物。在模板繼承裏,將保持模板做爲獨立頁面而不用加載其餘頁面,能夠操縱內容塊繼承它們。這使得模板更直觀、更有效和易管理編程
固然,也有不適合使用Smarty的地方。例如,須要實時更新的內容,須要常常從新編譯模板,因此這類型的程序使用Smarty會使模板處理速度變慢。另外,在小項目中也不適合使用Smarty模板,小項目由於項目簡單而前端與後端兼於一人的項目,使用Smarty會在必定程度上喪失PHP開發迅速的優勢後端
【安裝】api
安裝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="smarty@example.com"} <select name="company_id"> {html_options options=$companies selected=$company_id} </select>
Smarty有幾種不一樣類型的變量,變量的類型取決於它的前綴符號是什麼(或者被什麼符號包圍)。Smarty的變量能夠直接被輸出或者做爲函數屬性和調節器(modifiers)的參數,或者用於內部的條件表達式等等。若是要輸出一個變量,只要用定界符將它括起來就能夠
一、從PHP分配的變量
index.php: $smarty = new Smarty; $smarty->assign('Contacts',array('fax' => '555-222-9876','email' => 'zaphod@slartibartfast.com')); $smarty->display('index.tpl'); index.tpl: <{$Contacts.fax}><br> <{$Contacts.email}><br> OUTPUT: 555-222-9876<br> zaphod@slartibartfast.com<br>
二、從配置文件讀取的變量
加載配置文件後,配置文件中的變量須要用兩個井號"#"包圍或者是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'); ?>
三、配置文件裏分區域的變量
foo.conf: [a] x=1 [b] x=2 [c] x=3 <!-- main.tpl --> <{config_load file='foo.conf' section="a"}> <{#x#}> output: 1
四、模板裏定義的變量
<{$name='Bob'}> The value of $name is <{$name}>. output: The value of $name is Bob.
五、保留變量
$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>
{$var=...} 變量賦值
這是{assign}函數的簡寫版,能夠直接賦值給模版,也能夠爲數組元素賦值
<{$name='Bob'}>The value of $name is <{$name}>. output: The value of $name is Bob.
{append} 追加
{append}用於在模板執行期間創建或追加模板變量數組
<{append var='name' value='Bob' index='first'}> <{append var='name' value='Meyer' index='last'}> <{* 或者 *}> <{append 'name' 'Bob' index='first'}> <{* 簡寫 *}> <{append 'name' 'Meyer' index='last'}> <{* 簡寫 *}> The first name is <{$name.first}>.<br> The last name is <{$name.last}>. output: The first name is Bob.The last name is Meyer.
{assign} 賦值
{assign}用來在模板運行時爲模板變量賦值
<{assign var="name" value="Bob"}> <{assign "name" "Bob"}> <{* 簡寫 *}> The value of $name is <{$name}>. output: The value of $name is Bob.
{config_load}
{config_load}用來從配置文件中加載config變量(#variables#)到模版
foo.conf: [a] x=1 [b] x=2 [c] x=3 <!-- main.tpl --> <{config_load file='foo.conf' section="a"}> <{#x#}> output: 1
{for} 循環
{for}、{forelse}標籤用來建立一個簡單循環,支持如下不一樣的格式:
{for $var=$start to $end}步長爲1的簡單循環;
{for $var=$start to $end step $step}其它步長循環
當循環無迭代時執行{forelse}
<ul> <{for $foo=1 to 3}> <li><{$foo}></li><{/for}> </ul> output: <ul> <li>1</li> <li>2</li> <li>3</li> </ul>
<ul> <{for $foo=2 to 10 max=3}> <li><{$foo}></li><{/for}> </ul> output: <ul> <li>2</li> <li>3</li> <li>4</li> </ul>
{while}循環
隨着一些特性加入到模版引擎,Smarty的{while}循環與php的while語句同樣富有彈性。每個{while}必須與一個{/while}成對出現,全部php條件和函數在它身上一樣適用,諸如||、or、&&、and、is_array()等等
下面是一串有效的限定符,它們的左右必須用空格分隔開,注意列出的清單中方括號是可選的,在適用狀況下使用相應的等號(全等或不全等)
{while $foo > 0} {$foo--} {/while}
{foreach},{foreachelse}遍歷
{foreach}用來遍歷數據數組,{foreach}與{section}循環相比更簡單、語法更乾淨,也能夠用來遍歷關聯數組
{foreach $arrayvar as $itemvar} {foreach $arrayvar as $keyvar=>$itemvar}
{foreach}循環能夠嵌套;數組變量一般是(另)一個數組的值,用來指導循環的次數,能夠爲專有循環傳遞一個整數;當數組變量無值時執行{foreachelse};
{foreach}的屬性是@index、@iteration、@first、@last、@show、@total;
能夠用循環項目中的當前鍵({$item@key})代替鍵值變量
<{$myColors['a'] = 'red'}> <{$myColors['b'] = 'green'}> <{$myColors['c'] = 'blue'}> <ul> <{foreach $myColors as $color}> <li><{$color@key}>:<{$color}></li> <{/foreach}> </ul> output: <ul> <li>a:red</li> <li>b:green</li> <li>c:blue</li> </ul>
@index:包含當前數組的下標,開始時爲0
@iteration:包含當前循環的迭代,老是以1開始,這點與index不一樣。每迭代一次值自動加1
@first:當{foreach}循環第一個時first爲真
@last:當{foreach}迭代到最後時last爲真
@show:檢測{foreach}循環是否無數據顯示,show是個布爾值(true or false)
@total:包含{foreach}循環的總數(整數),能夠用在{forach}裏面或後面
{break}:中止/終止數組迭代
{continue}:停止當前迭代而開始下一個迭代/循環
<{$myColors['a'] = 'red'}> <{$myColors['b'] = 'green'}> <{$myColors['c'] = 'blue'}> <{$myColors['d'] = 'pink'}> <{$myColors['e'] = 'yellow'}> <ul> <{foreach $myColors as $color}> <{if $color@first}> <li><b><{$color@iteration}>:<{$color@index}>:<{$color@key}>:<{$color}></b></li> <{elseif $color@last}> <li><b><{$color@iteration}>:<{$color@index}>:<{$color@key}>:<{$color}></b></li> <{else}> <li><{$color@iteration}>:<{$color@index}>:<{$color@key}>:<{$color}></li> <{/if}> <{foreachelse}> no result... <{/foreach}> </ul> output: <ul> <li><b>1:0:a:red</b></li> <li>2:1:b:green</li> <li>3:2:c:blue</li> <li>4:3:d:pink</li> <li><b>5:4:e:yellow</b></li> </ul>
{if}{elseif}{else} 條件
隨着一些特性加入到模版引擎,Smarty的{if}語句與php的if語句同樣富有彈性。每個{if}必須與一個{/if}成對出現,容許使用{else}和{elseif},全部php條件和函數在這裏一樣適用,諸如||、or、&&、and、is_array()等等
<{if $name == 'Fred' || $name == 'Wilma'}> ... <{/if}> <{* 容許使用圓括號 *}> <{if ( $amount < 0 or $amount > 1000 ) and $volume >= #minVolAmt#}> ... <{/if}> <{* 能夠嵌入函數 *}> <{if count($var) gt 0}> ... <{/if}> <{* 數組檢查 *}> <{if is_array($foo) }> ..... <{/if}> <{* 是否空值檢查 *}> <{if isset($foo) }> ..... <{/if}> <{* 測試值爲偶數仍是奇數 *}> <{if $var is even}> ... <{/if}> <{if $var is odd}> ... <{/if}> <{if $var is not odd}> ... <{/if}> <{* 測試var可否被4整除 *}> <{if $var is div by 4}> ... <{/if}> <{* 測試發現var是偶數,2個爲一組,也就是0=even, 1=even, 2=odd, 3=odd, 4=even, 5=even, 等等 *}> <{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}>
{include}
{include}標籤用於在當前模板中包含其它模板。當前模板中的任何有效變量在被包含模板中一樣可用
必須指定file屬性,該屬性指明模板資源的位置
變量能夠做爲屬性參數傳遞給被包含模板,任何明確傳遞給被包含模板的變量只在被包含文件的做用域中有效。若是傳遞的屬性變量在當前模板中有同名變量,那麼傳遞的屬性變量將覆蓋當前模板變量
<!-- main.tpl --> <{include file="header.tpl" test="小火柴"}> <!-- header.tpl --> <{$test}> <{$test="aaa"}><br> <{$test}> output: 小火柴 aaa
{function}
{function}用來在模板中建立函數,能夠像調用插件函數同樣調用它們
咱們不寫一個表達內容的插件,而是讓它保留在模板中,一般這是個更易於管理的選擇。同時,它也簡化了對數據的遍歷,例如深度嵌套菜單。另外能夠在模板中直接使用{funcname...}函數。
{function}標籤必須包含模板函數名的name屬性,該name標籤名必須可以調用模板函數
默認變量值應能做爲屬性傳遞到模板函數,當模板函數被調用的時候,默認值應能被複寫
在模板函數內部應能使用被調用模板的全部變量值,在模板函數中更改或新建變量的值必須具局部做用域,並且在執行模板函數後這些變量值在被調用模板內部應不可見
調用函數時,能夠直接使用函數名,或者使用{call}
<!-- main.tpl --> <{function name=test a=0 b=0}> <{$a}>+<{$b}>=<{$a+$b}> <{/function}> <{test}><br> <{test a=1 b=2}><br> <{call test a=3 b=3}><br> output: 0+0=0 1+2=3 3+3=6
Smarty中的插件老是按需加載。只有在模板腳本中調用特定的調節器、函數、資源插件等時纔會自動加載。此外,每一個插件只加載一次,即使在同一個請求中存在幾個不一樣的Smarty實例同時運行
插件目錄能夠是一個包含路徑的字符串或包含多個路徑的數組。安裝插件的時候,將插件簡單地置於其中一個目錄下,Smarty會自動識別使用
插件文件和函數必須遵循特定的命名約定以便Smarty識別
插件文件必須命名以下:
type.name.php
其中type爲下面這些插件類型中的一種:
function
modifier
block
compiler
prefilter
postfilter
outputfilter
resource
insert
name爲合法標識符,僅包含字母、數字和下劃線
function.html_select_date.php, resource.db.php, modifier.spacify.php
插件內的函數應遵循以下命名約定
smarty_type_name ()
若是調節器(modifier)命名爲foo,那麼按規則函數爲smarty_modifier_foo()。若是指定的插件文件不存在或文件、函數命名不合規範,Smarty會輸出對應的錯誤信息
Smarty既可自動從文件系統加載插件,也可在運行時經過register_* API函數註冊插件。固然,也能夠經過unregister_* API函數卸載已經載入的插件
對於只在運行時註冊的插件函數沒必要遵照命名約定
若是某個插件依賴其它插件的某些功能(事實上,一些插件被綁定在Smarty中),那麼能夠經過以下方法加載須要的插件:
<?php require_once $smarty->_get_plugin_filepath('function', 'html_options'); ?>
按照慣例,Smarty對象一般做爲最後一個參數傳遞給插件,但有兩個例外:一、調節器不須接受Smarty對象的傳遞;二、爲了向前兼容舊版Smarty,塊插件將$repeat排在Smarty對象後面做爲最後一個參數($smarty做爲倒數第二個參數)
【模板函數】
void smarty_function_name($params, $smarty); array $params; object $smarty;
模板傳遞給模板函數的全部屬性都包含在關聯數組$params中
在模板中,函數的輸出內容(返回值)在原位置用函數標籤代替,例如{fetch}函數。做爲另外一種選擇,函數也能夠單純地用來作些非輸出內容的任務,如{assign}函數
若是函數須要分配(俗話說的賦值)一些變量給模板或者使用Smarty提供的一些函數,能夠經過$smarty對象實現,如$smarty->foo()
//function.eightball.php <?php function smarty_function_eightball($params, $smarty){ $answers = array('Yes', 'No','No way','Outlook not so good','Ask again soon','Maybe in your reality'); $result = array_rand($answers); return $answers[$result];} ?> <!-- main.tpl --> Question: Will we ever have time travel?<br> Answer: <{eightball}>.
除了使用以上方式,還可使用registerPlugin()方式來進行插件註冊,可是因爲與PHP代碼混合在一塊兒,不建議使用
registerPlugin()
void registerPlugin(string type, string name, mixed callback, bool cacheable, mixed cache_attrs);
registerPlugin()方法在腳本中註冊函數或方法做爲插件。其參數以下:
「type」定義插件的類型,其值爲下列之一:「function」、「block」、「compiler」和「modifier」
「name」定義插件的函數名
「callback」爲定義的php回調函數,其類型爲下列之一:
一、包含函數名的字符串;
二、格式爲(&$object, $method)的數組,其中,&$object爲引用對象,$method爲包含方法名的字符串;
三、格式爲($class, $method)的數組,其中,$class爲類名,$method爲類中的方法。
「cacheable」和「cache_attrs」參數大多狀況下能夠省略
<?php header("content-type:text/html;charset=utf-8"); require './init.inc.php'; function eightball($params, $smarty){ $answers = array('Yes', 'No','No way','Outlook not so good','Ask again soon','Maybe in your reality'); $result = array_rand($answers); return $answers[$result]; } $smarty -> registerPlugin('function', 'test', 'eightball'); $smarty -> display('main.tpl'); ?> <!-- main.tpl --> Question: Will we ever have time travel?<br> Answer: <{test}>. <br>
【調節器】
調節器是一些簡短的函數,這些函數被應用於顯示模板前做用於一個變量,或者其它情形中。調節器能夠鏈接起來(執行)
mixed smarty_modifier_name($value, $param1); mixed $value; [mixed $param1, ...];
調節器插件的第一個參數應該直接了當地聲明處理什麼類型(能夠是字符串、數組、對象等等這些類型)。其它的參數是可選的,取決於執行的操做類型。調節器必須返回處理結果
//modifier.u.php <?php function smarty_modifier_u($str){ return ucwords($str); } ?> <!-- main.tpl --> <{$testValue = 'Question: Will we ever have time travel?' }><br> <{$testValue}><br> <{$testValue|u}><br> output: Question: Will we ever have time travel? Question: Will We Ever Have Time Travel?
【塊函數】
void smarty_block_name($params, $content, $smarty, &$repeat); array $params; mixed $content; object $smarty; boolean &$repeat;
塊函數的形式是這樣的:{func} .. {/func}。換句話說,他們被封閉在一個模板區域內,而後對該區域的內容進行操做。塊函數優先於同名的自定義函數,換句話說,不能同時使用自定義函數{func}和塊函數{func} .. {/func}。
默認地,函數實現會被Smarty調用兩次:一次是在開始標籤,另外一次是在閉合標籤
從Smarty3.1開始打開標籤回調(函數)的返回值一樣會被顯示
只有塊函數的開始標籤具備屬性。全部屬性包含在做爲關聯數組的$params變量中,經由模板傳遞給模板函數。當處理閉合標籤時,函數一樣可訪問開始標籤的屬性
$content變量值取決於函數是被開始標籤調用仍是被閉合標籤調用。假如是開始標籤,變量值將爲NULL,若是是閉合標籤,$content變量值爲模板塊的內容。請注意這時模板塊已經被Smarty處理過,所以所接收到的是模板的輸出而不是模板資源
&$repeat參數經過引用傳遞給函數執行,併爲其提供控制塊顯示多少次的可能性。默認狀況下,在首次調用塊函數(塊開始標籤)時,&$repeat變量爲true,在隨後的全部塊函數(閉合標籤)調用中其值始終爲false。函數每次執行返回的&$repeat值爲true時,{func} .. {/func}之間的內容會被求值,同時參數$content裏的新塊內容會再次調用執行函數
若是嵌套了塊函數,能夠經過$smarty->_tag_stack變量訪問找出父塊函數。只須對塊函數運行一下var_dump(),函數結構就能夠一目瞭然了
//block.s.php <?php function smarty_block_s($params, $content, $smarty, &$repeat){ return substr($content,0,$params['num']+1); } ?> <!-- main.tpl --> <{$testValue = 'Question: Will we ever have time travel?' }><br> <{$testValue}><br> <{s num="5"}> <{$testValue}> <{/s}> output: Question: Will we ever have time travel? Quest
繼承帶來了模板面向對象概念(oop),它容許定義一個或多個基模板供子模板繼承。繼承意味着子模板可覆蓋全部或部份父模板中命名相同的塊區域
模板繼承是一種編譯時進程,其將創建一個獨立的編譯模板文件。與對應的基於載入{include}子模板解決方案相比,當解釋模板時,前者有更好的性能
{extends} 繼承
{extends}標籤用在模板繼承中子模版對父模板的繼承
{extends}標籤用在模版中的第一行
若是子模板用{extends}標籤繼承父模板,那麼它只能包含{block}標籤(內容),其它任何模板內容都將忽略
使用此語法爲模板資源繼承$template_dir目錄外的文件
{extends file='parent.tpl'} {extends 'parent.tpl'} {* short-hand *}
<!-- parent.tpl--> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> 我是父模板中的文字 </body> </html> <!-- child.tpl--> <{extends 'parent.tpl'}>
<!-- parent.php--> <?php header("content-type:text/html;charset=utf-8"); require './init.inc.php'; $smarty -> display('parent.tpl'); ?> <!-- child.php--> <?php header("content-type:text/html;charset=utf-8"); require './init.inc.php'; $smarty -> display('child.tpl'); ?>
{block} 塊
{block}用來給模板繼承定義一個模板資源的命名區域。子模板的{block}資源區域將會取代父模板中的相應區域。{block}能夠嵌套
任意的子、父模板{block}區域能夠彼此結合。能夠經過子{block}定義使用append、prepend選項標記追加或預置父{block}內容。使用{$smarty.block.parent}可將父模板的{block}內容插入至子{block}內容中的任何位置。使用{$smarty.block.child}可將子模板{block}內容插入至父{block}內容中的任何位置
[注意]子模板不能定義任何內容,除了須要覆蓋父模板的{block}標籤塊,全部在{block}標籤外的內容將被自動移除
<!-- parent.tpl--> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <{block name="one"}> one <{/block}><br> <{block name="two"}> two <{/block}><br> <{block name="three"}> three <{/block}><br> <{block name="four"}> four <{$smarty.block.child}> <{/block}><br> <{block name="five"}> five <{/block}><br> </body> </html> <!-- child.tpl--> <{extends 'parent.tpl'}> <{block name="one"}> 1 <{/block}><br> <{block name="two" prepend}> 2 <{/block}><br> <{block name="three" append}> 3 <{/block}><br> <{block name="four"}> 4 <{/block}><br> <{block name="five"}> 5 <{$smarty.block.parent}> <{/block}><br>
block區域以外的內容不會顯示
<!-- parent.php--> <?php header("content-type:text/html;charset=utf-8"); require './init.inc.php'; $smarty -> display('parent.tpl'); ?> <!-- child.php--> <?php header("content-type:text/html;charset=utf-8"); require './init.inc.php'; $smarty -> display("child.tpl"); ?>