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"。
屬性: