最近學(xué)習smarty的時(shí)候,下載的是官方的最新版本:smarty3X,使用之前卻沒(méi)有去讀一下它的使用手冊,而自己所學(xué)教程仍是版本2,給自己帶來(lái)了不少的麻煩.
所以,結合其他的總結資料,把smarty 3變化記錄下來(lái).
Smarty3 的API已經(jīng)被重構過(guò)以更好的面向結構話(huà)和語(yǔ)法一致性。但是Smarty2的API仍然是支持的,但是會(huì )出提示。
當然,也可以手動(dòng)disable掉這個(gè)提示,但是強烈推薦你將你的語(yǔ)法升級到適應Smarty3的語(yǔ)法
Smarty3中所有的方法命名都采用”fooBarBaz”的方式,而且,所有的Smarty屬性都含有g(shù)etters和setters,舉例:
老版本中設置Cache的路徑
現在可以這樣作:
1 | $smarty->setCacheDir('foo/') |
并且可以通過(guò)如下方法獲?。?/p>
目錄結構
04 | /libs/sysplugins/ #內部plugin |
06 | /plugins/ #外部plugin,可自由擴充 |
09 | /templates/ #模板,可以是純php或傳統的smarty模板 |
簡(jiǎn)單調用
1 | require('Smarty.class.php'); |
3 | $smarty->assign('foo','bar'); |
4 | $smarty->display('index.tpl');))) |
區別
雖然Smarty3在模板使用起來(lái)和以前沒(méi)有區別,但是其實(shí)內部邏輯是截然不同的,卻也是能夠和2進(jìn)行兼容.
除了以下幾點(diǎn)
- Smarty3只能運行在PHP5環(huán)境下,不再支持PHP4.
- {php}標簽默認是關(guān)閉的,可以通過(guò)如下方式打開(kāi)$smarty->allow_php_tag=true
- 模板標簽將不支持空格,如{ $abc }在Smarty2中可以識別的,但是3里頭就不行了,必須這樣{$abc},這樣是為了能夠更好的支持javascript和css.
- Smarty3的API有一定的不同,但是仍然支持Smarty2
新的功能
表達式
支持更加隨意的表達式
2 | {$foo = strlen($bar)} 變量支持PHP函數 |
3 | {assign var=foo value= $x+$y} 屬性支持表達式 |
4 | {$foo = myfunct( ($x+$y)*3 )} 函數參數支持表達式 |
引號中可以使用變量
1 | {$foo="this is message {counter}"} |
可以在模板里頭定義數組
1 | {assign var=foo value=[1,2,3]} |
2 | {assign var=foo value=['y'=>'yellow','b'=>'blue']} |
3 | {assign var=foo value=[1,[9,8],3]} |
簡(jiǎn)單的變量賦值
可以給指定的數組元素賦值,如果變量存在但不是數組,會(huì )先轉換成數組,再進(jìn)行賦值
同上,可以給數組添加值
對象的屬性支持”.”操作符
1 | {$foo.a.b.c} => $foo['a']['b']['c'] |
2 | {$foo.a.$b.c} => $foo['a'][$b]['c'] |
3 | {$foo.a.{$b+4}.c} => $foo['a'][$b+4]['c'] |
4 | {$foo.a.{$b.c}} => $foo['a'][$b['c']] |
變量名中支持變量
3 | $foo_{$x+$y} 變量名中可以支持表達式 |
4 | $foo_{$bar}_buh_{$blar} 變量名包含多個(gè)變量 |
5 | {$foo_{$x}} 如果$x是1,則輸出$foo_1 |
支持對象鏈,即是對象方法的連續調用,很像jquery
1 | {$object->method1($x)->method2($y)} |
{for}標簽支持類(lèi)似loop一樣的循環(huán)
1 | {for $x=0, $y=count($foo); $x<$y; $x++} .... {/for} |
在FOR循環(huán)中可以通過(guò)如下特殊標示符限定位置:
1 | $x@iteration 當前循環(huán)次數 |
4 | $x@last 循環(huán)最后一次新的foreach語(yǔ)法 |
新的foreach語(yǔ)法
1 | {foreach $myarray as $var}...{/foreach} |
同樣是foreach里頭的特殊表示符,看的就明白,不翻譯了……
1 | $var@key foreach $var array key |
2 | $var@iteration foreach current iteration count (1,2,3...) |
3 | $var@index foreach current index count (0,1,2...) |
4 | $var@total foreach $var array total |
5 | $var@first true on first iteration |
6 | $var@last true on last iteration |
支持while循環(huán)
2 | {while $x lt 10}...{/while} |
可以直接使用PHP的函數
新增加了一個(gè){function}的標簽,可以定義一個(gè)可供調用的函數塊.
1 | {function}...{/function} |
該標簽必須有一個(gè)name屬性,用來(lái)指名該函數名稱(chēng),也是調用的時(shí)候需要用到的
下面是一個(gè)實(shí)例:
02 | {function name=menu level=0} |
04 | {foreach $data as $entry} |
07 | {menu data=$entry level=$level+1} |
16 | {$menu = ['item1','item2','item3' => ['item3-1','item3-2','item3-3' => |
17 | ['item3-3-1','item3-3-2']],'item4']} |
22 | 代碼塊不緩存,可以使用{nocache}標簽默認是關(guān)閉的 |
24 | {nocache} ... {/nocache} |
30 | {foo bar="baz" nocache=true} |
31 | {foo bar="baz" nocache} |
變量作用域和存儲
在Smarty2中,所有的變量都存儲在Smarty對象中,因此所有的變量在所有模板和子方法中都可以獲取.
在Smarty3中,可以自己定義的將變量存儲在主Smarty對象中,或者用戶(hù)自己定義的對象中,甚至是用戶(hù)自己的模板對象中,而且這些對象可以通過(guò)鏈式串接起來(lái).
在鏈的末尾的對象可以獲取到對象鏈之前的對象中存儲的所有變量.
Smarty對象必須是鏈的根對象,但是對象鏈卻是可以獨立于Smarty對象存在的所有的Smarty的賦值方法都可以用在data對象或者模板對象.
除了上面說(shuō)幾個(gè)方面,全局變量還有一種特殊的存儲方式.
一個(gè)Smarty的數據對象(data Object)可以通過(guò)如下方式創(chuàng )建
1 | $data = $smarty->createData(); |
2 | $data->assign('foo','bar'); |
3 | $data->config_load('my.conf'); |
5 | $data = $smarty->createData($smarty); |
7 | $data2= $smarty->createData($data); |
創(chuàng )建一個(gè)模板對象(template object) 可以通過(guò)createTemplate方法,它的參數傳遞和fetch()/display()方法一致.
函數定義方式
1 | function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null) |
舉例
1 | $tpl = $smarty->createTemplate('mytpl.tpl'); |
2 | $tpl->assign('foo','bar'); |
3 | $tpl->config_load('my.conf'); |
5 | $tpl = $smarty->createTemplate('mytpl.tpl',$smarty); |
fetch()/display() 兩個(gè)方法將隱式的創(chuàng )建一個(gè)模板對象
如果不指定父對象,則默認父對象將指向Smarty對象
如果一個(gè)模板是通過(guò)include方式調用的,則子模板的父對象將指向引用它的模板對象
所有當前模板變量和父對象的模板對象都是可以獲取的,但是如果是通過(guò){assign}或者{$foo=…}這樣的方法創(chuàng )建或者修改變量
則它的作用域將只停留在當前模板對象
Smarty3中,在賦值變量的時(shí)候可以指定它的作用域,有4個(gè)值local,parent,root,global
1 | {assign var=foo value='bar'} |
3 | {assign var=foo value='bar' scope='local'} |
4 | {assign var=foo value='bar' scope='parent'} |
5 | {$foo='bar' scope='parent'} |
6 | {assign var=foo value='bar' scope='root'} |
7 | {$foo='bar' scope='root'} |
8 | {assign var=foo value='bar' scope='global'} |
9 | {$foo='bar' scope='global'} |
擴展
Smarty3的擴展都是繼承至Smarty – Internal – PluginBase的類(lèi)
所有的擴展都包含一個(gè)Smarty對象實(shí)例的$this->smarty屬性
模板繼承
你可以在模板中寫(xiě){block} … {/block}快,并且這些塊可以在子模板中進(jìn)行覆蓋
04 | <title>{block name='title'}My site name{/block}</title> |
07 | <h1>{block name='page-title'}Default page title{/block}</h1> |
09 | {block name='content'} |
3 | {extends file='parent.tpl'} |
03 | {extends file='child.tpl'} |
05 | {block name='title'}Home - {$smarty.block.parent}{/block} |
06 | {block name='page-title'}My home{/block} |
08 | {foreach $images as $img} |
可以通過(guò)extends標簽來(lái)指定被繼承的模板,并在子模板中通過(guò)重寫(xiě)父模板的同名block塊,達到覆蓋的目的
同時(shí),可以通過(guò){$smarty.block,parent}獲取到父block的內容
上面的grandchild.tpl將生成如下內容
3 | <div id="content"><img src="/example.jpg" alt="image" /> |
4 | <img src="/example2.jpg" alt="image" /> |
5 | <img src="/example3.jpg" alt="image" /></div> |
注意,在子模板中,所有在{block} … {/block}之外的內容都將被忽略,這種繼承支持多文件,多重繼承,意味著(zhù)可以無(wú)線(xiàn)的繼承下去.還可通過(guò){block}的append和prepend屬性來(lái)插入父模板結構中.