Smarty是PHP用的一套樣版引擎
這東西就像是.NET的MasterPage,可以把頁面Template(樣版化)動態輸出
這樣一來就可以標準化網頁,不過個人不喜歡MasterPage的作法就是了
之前旗標也有出Smarty的書籍,不過網路上已經也有很多相關教學了
Smarty並不是很龐大,說明手冊花個兩三個小時大概就能讀完了
加上有前人很熱情的放出中文化中說明手冊,要自學也不用花什麼工夫
附上幾個我參考到的網站
- Smarty 官網:這是一定會參考到的 最新的文件還有下載
- Smarty入門:整理非常好的部落格,對於基礎功能跟觀念看這篇就對了
- Smarty中文說明手冊:英文不好,還有這個可以看,台灣PHP聯盟上的資源
當初覺得Smarty應該要花不少時間去學,真的開始看說明手冊以後其實不然
不考慮研究核心code的話,其實很快就能把整個功能面跟觀念說完了
上面幾篇文章都說的非常清楚了,下面只是我一些研究過程的隨筆
Extended Setup這篇有附上一段程式碼,這段code很重要
class Smarty_GuestBook extends Smarty {
function Smarty_GuestBook()
{
$this->Smarty();
$this->template_dir = '/web/www.example.com/guestbook/templates/';
$this->compile_dir = '/web/www.example.com/guestbook/templates_c/';
$this->config_dir = '/web/www.example.com/guestbook/configs/';
$this->cache_dir = '/web/www.example.com/guestbook/cache/';
$this->caching = true;
$this->assign('app_name', 'Guest Book');
}
}
他建議我們擴充Smarty類別,把一些設定都先設定好
一開始要指定幾個資料夾,template_dir、compile_dir、config_dir、cache_dir
這四個最常用的,其他還有一些延伸資料夾可以指定,但是在此先不探討
- template_dir:樣版網頁放置地方,使用display() 函式的時候會去template_dir指定的地方尋找樣版
預設是./templates - compile_dir:Smarty會把樣版網頁先編譯成對應格式,這是編譯結果放的網頁,預設是./templates_c
- config_dir:Smarty允許事先弄一些設定檔出來,預設是放./configs
使用config_load() 載入config的時候他會去config_dir指定的資料夾找檔案
他官網提供的config編寫範例
# global variables
pageTitle = "Main Menu"
bodyBgColor = #000000
tableBgColor = #000000
rowBgColor = #00ff00
[Customer]
pageTitle = "Customer Info"
[Login]
pageTitle = "Login"
focus = "username"
Intro = """This is a value that spans more
than one line. you must enclose
it in triple quotes."""
# hidden section
[.Database]
host=my.example.com
db=ADDRESSBOOK
user=php-user
pass=foobar - cache_dir:如果有設定快取(caching是true),他會產生一份compile_dir裡面編譯檔的最後輸出
預設資料夾是 ./cache
而我照自己的需求去擴展一個Smarty,並創造一個smartyDir資料夾,下面放Smarty須要用到的資料夾
我把類別庫放在Smarty/libs下面,只要include其中的Smarty.class.php就可以了
include_once ('Smarty/libs/Smarty.class.php');
define("APPDIR","smartyDir/");
class MySmarty extends Smarty{
function MySmarty(){
$this->template_dir=APPDIR."templates";
$this->compile_dir=APPDIR."templates_c";
$this->config_dir=APPDIR."config_dir";
$this->cache_dir=APPDIR."cache";
}
/*更改阻斷符號 預設是{跟}*/
function setDelimiter($Lcode,$Rcode)
{
$this->left_delimiter=$Lcode;
$this->right_delimiter="$Rcode";
}
}
?>
我先在templates資料夾裡面建一個樣版檔案mytemp.tp
mytemp.tp內容
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
{$page}
</body>
</html>
其中{$page}是Smarty可用的變數,將來可以用來替換自己想要的內容
變數的使用方法可以參考Variables這篇說明文件
簡介幾種常用的方式
- {$foo} <-- displaying a simple variable (non array/object)
指派一般變數,使用assign指派內容
$tp1=new MySmarty();
$tp1->assign("foo","Hello"); - {$foo[4]} <-- display the 5th element of a zero-indexed array
指派一個陣列
$arr=array(1,2,3,4,5);
$tp1->assign("foo",$arr); - {$foo.bar} <-- display the "bar" key value of an array, similar to PHP $foo['bar']
指派關聯陣列
$arr=array('bar'=>'I am God');
$tp1->assign("foo",$arr); - {$foo->bar} <-- display the object property "bar"
- {$foo->barf()} <-- display the return value of object method "bar"
指派一個物件
class Foo{
var $bar;
function barf(){......}
}
$obj=new Foo();
$tp1->assign("foo",$obj); {#foo#} <-- display the config file variable "foo"
使用config_load() 載入的設定內容
ex:有個conf.txt內容是foo=MyGod
之後php程式碼的部分就可以用assign指派我們想要的內容
$tp2=new MySmarty();
$tp2->assign("page","Hello Smarty");/*指派Smarty變數內容*/
$tp2->caching=true;/*開啟快取*/
$tp2->display("mytemp.tp");/*顯示網頁*/
執行結果
題外話,一開始我一直以為display() 函式是去程式同一個資料夾找樣版
所以一開始我沒把樣版放在templates資料夾裡面
所以一直會出現錯誤訊息
Smarty error: unable to read resource........
那剛剛秀出網頁做了些什麼呢?
首先我display()去顯示templates資料夾下的mytemp.tp
之後會在我指定的編譯資料夾templates_c下產生一個編譯過的檔案%%9B^9B3^9B3C2773%%mytemp.tp.php,此時他還是一個php的動態檔
來看一下他編譯了什麼東西出來
<?php /* Smarty version 2.6.26, created on 2009-08-21 02:07:52
compiled from mytemp.tp */ ?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<?php echo $this->_tpl_vars['page']; ?>
</body>
</html>
原來的樣版檔案,變成一個我們都很熟悉的PHP檔,Smarty變數的部分被PHP碼所取代
但是這樣很慢,要把樣版(Template)解譯成PHP檔,又要把PHP檔編譯成網頁
所以Smarty提供了cache的機制
當我設定cache的時候,,他會在我指定的cache資料夾產生一個已經編譯好的靜態網頁
這樣下次要access的時候直接用這個就可以了,不用重新編譯
來看看cache的內容
130
a:4:{s:8:"template";a:1:{s:9:"mytemp.tp";b:1;}s:9:"timestamp";i:1250821113;s:7:"expires";i:1250824713;s:13:"cache_serials";a:0:{}}<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
Hello Smarty
</body>
</html>
除了原本編譯好的網頁之外,還有一串header包括了timestamp
cache並不會永遠存在,過了一段時間後就會被刪除,預設是一個小時
可以透過cache_lifetime修改生存時間
不過如果同個樣版有多種內容的話(ex:資料庫的資料),就必須設定cache_id作辨別
一般會用user下的query作hash來產生cache_id
另外我在寫程式的時候,發現他會跟css碼或者javascript相衝,因為他的阻斷符號是{跟}
正好跟css設定方法有衝突,可以透過left_delimiter跟right_delimiter重新設定阻斷符號
像我是設定成,這樣就不會跟css碼相衝了
$tp1->setDelimiter("<!--{","}--<");/*這是我自定的函式,請參考上方的MySmarty*/
之後我在標記Smarty變數就會從
......
{$page}
......
變成用下面這種方式
<!--{$page}-->
因為是用HTML註解的方式去從新包裝,這樣一來也比較不會有問題
其他更多的內容,包括註冊自己的函式跟區塊、if else 、loop迴圈等等,就請去翻說明手冊啦
手冊有更多詳盡的內容
都可以找到相對應的翻譯
備註:上面的連結Smarty中文說明手冊
沒有留言:
張貼留言