- 论坛徽章:
- 30
|
一、什么是smarty?
smarty是一个使用PHP写出来的模板PHP模板引擎,它提供了逻辑与外在内容的分离,简单的讲,目的就是要使用PHP程序员同美工分
离,使用的程序员改变程序的逻辑内容不会影响到美工的页面设计,美工重新修改页面不会影响到程序的程序逻辑,这在多人合作的项目
中显的尤为重要。
二、smarty优点:
1. 速度:采用smarty编写的程序可以获得最大速度的提高,这一点是相对于其它的模板引擎技术而言的。
2. 编译型:采用smarty编写的程序在运行时要编译成一个非模板技术的PHP文件,这个文件采用了PHP与HTML混合的方式,在下一次访
问模板时将WEB请求直接转换到这个文件中,而不再进行模板重新编译(在源程序没有改动的情况下)
3. 缓存技术:smarty选用的一种缓存技术,它可以将用户最终看到的HTML文件缓存成一个静态的HTML页,当设定smarty的cache属性为
true时,在smarty设定的cachetime期内将用户的WEB请求直接转换到这个静态的HTML文件中来,这相当于调用一个静态的HTML文件。
4. 插件技术:smarty可以自定义插件。插件实际就是一些自定义的函数。
5. 模板中可以使用if/elseif/else/endif。在模板文件使用判断语句可以非常方便的对模板进行格式重排。
三、不适合使用smarty的地方:
1. 需要实时更新的内容。例如像股票显示,它需要经常对数据进行更新,这类型的程序使用smarty会使模板处理速度变慢。
2. 小项目。小项目因为项目简单而美工与程序员兼于一人的项目,使用smarty会丧失php开发迅速的优点。
四、安装smarty类:
安装smarty的环境:php版本4.06以上版本。
安装smarty方法非常简单,从
http://samrty.php.net中下载smarty.t...将LIB中所有文件
拷入comm目录,完成基本安装.
其它高级安装使用方法请看手册.
五、smarty在模板中的使用:
本节通过几个实例来讲一讲smarty的使用。smarty模板通常使用.tpl来标识,有些人为了美工方便,将扩展名直接写成.html,也是可以
的。本文中采用smarty标准写法:以.tpl来表示为一个smarty模板。
PHP代码:--------------------------------------------------------------------------------
实例1:
先来看一个简单的例子。
=====================================================
index.tpl
=====================================================
{* 显示是smarty变量识符里的用*包含的文字为注释内容 *}
{include file="header.tpl"}{*页面头*}
大家好,我叫{$name}, 欢迎大家阅读我的smarty学习材料。
{include file="foot.tpl"}{*页面尾*} 上边的这个例子是一个tpl模板,其中:
1. {**}是模板页的注释,它在smarty对模板进行解析时不进行任何输出,仅供模板设计师对模板进行注释。
2. {include file="xxx.tpl"}使用此句将一个模板文件包含到当前页面中,例子中将在网站中公用事的head.tpl与foot.tpl进行了包含,你可以
这样想,使用这一句将xxx.tpl中的内容全部复制在当前语句处。当然,你不使用这一句也可以,将XXX.tpl中的内容复制到当前语句处
也是完全可以了。
3.{$name}: 模板变量,smarty中的核心组成,采用smarty定义的左边界符{与右边界符}包含着、以PHP变量形式给出,在smarty程序中将使用
$smarty->assign("name", "李晓军");将模板中的$name替换成“李晓军”三个字。
整个实例源程序如下:
=============================
header.tpl
=============================
大师兄smarty教程
===============================
foot.tpl
===============================
CopyRight(C) by 大师兄 2004年8月
=====================================================
index.tpl
=====================================================
{* 显示是smarty变量识符里的用*包含的文字为注释内容 *}
{include file="header.tpl"}{*页面头*}
大家好,我叫{$name}, 欢迎大家阅读我的smarty学习材料。
{include file="foot.tpl"}{*页面尾*} ================================================
index.php
================================================ templates("./templates"); //设置模板目录
$smarty->templates_c("./templates_c"); //设置编译目录
//----------------------------------------------------
//左右边界符,默认为{},但实际应用当中容易与JavaScript
//相冲突,所以建议设成或其它。
//----------------------------------------------------
$smarty->left_delimiter = "{";
$smarty->right_delimiter = "}";
$smarty->assign("name", "李晓军"); //进行模板变量替换
//编译并显示位于./templates下的index.tpl模板
$smarty->display("index.tpl");
?>
最终执行这个程序时将显示为:
================================
执行index.php
================================
大师兄smarty教程
大家好,我叫李晓军, 欢迎大家阅读我的smarty学习材料。
CopyRight(C) by 大师兄 2004年8月
the second part
这个例子是综合使用smarty模板参数的一个例子,这些参数用来控制模板的输出,我只选其中几个,其它的参数你去看参考吧。
================================================
exmple2.tpl
================================================
大师兄smarty示例2
1. 第一句首字母要大写:{$str1|capitalize}
2. 第二句模板变量 + 李晓军:{$str2|cat:"李晓军"}
3. 第三句输出当前日期:{$str3|date_format:"%Y年%m月%d日"}
4. 第四句.php程序中不处理,它显示默认值:{$str4|default:"没有值!"}
5。第五句要让它缩进8个空白字母位,并使用"*"取替这8个空白字符:
{$str5|indent:8:"*"}}
6. 第六句把TEACHerLI@163.com全部变为小写:{$str6|lower}
7. 第七句把变量中的teacherli替换成:李晓军:{$str7|replace:"teacherli":"李晓军"}
8. 第八句为组合使用变量修改器:{$str8|capitalize|cat:"这里是新加的时间:"|date_format:"%Y年%m月%d日"|lower}
===============================================
example2 .php
=============================================== templates("./templates"); //设置模板目录
$smarty->templates_c("./templates_c"); //设置编译目录
//----------------------------------------------------
//左右边界符,默认为{},但实际应用当中容易与JavaScript
//相冲突,所以建议设成或其它。
//----------------------------------------------------
$smarty->left_delimiter = "{";
$smarty->right_delimiter = "}";
$smarty->assign("str1", "my name is xiao jun, li."); //将str1替换成My Name Is Xiao Jun, Li.
$smarty->assign("str2", "我的名字叫:"); //输出: 我的名字叫:李晓军
$smarty->assign("str3", "公元"); //输出公元2004年8月21日(我的当前时间)
//$smarty->assign("str4", ""); //第四句不处理时会显示默认值,如果使用前面这一句则替换为""
$smarty->assign("str5", "前边8个*"); //第五句输出:********前边8个*
$smarty->assign("str6", "TEACHerLI@163.com"); //这里将输出teacherli@163.com
$smarty->assign("str7", "this is teacherli"); //在模板中显示为:this is 李晓军
$smarty->assign("str8", "HERE IS COMBINING:");
//编译并显示位于./templates下的index.tpl模板
$smarty->display("example2.tpl");
?>
最终输出效果:
======================================================
example2.php输出效果:
======================================================
大师兄smarty示例2
1. 第一句首字母要大写:My Name Is Xiao Jun, Li.
2. 第二句模板变量 + 李晓军:我的名字叫:李晓军
3. 第三句输出当前日期:公元2004年8月21日
4. 第四句.php程序中不处理,它显示默认值:没有值!
5。第五句要让它缩进8个空白字母位,并使用"*"取替这8个空白字符:
********前边8个*
6. 第六句把TEACHerLI@163.com全部变为小写:teacherli@163.com
7. 第七句把变量中的teacherli替换成:李晓军:this is 李晓军
8. 第八句为组合使用变量修改器:Here is Combining:这里是新加的时间:2004年8月21日
在模板中的这些参数被称为变量修改器(variable modifiers),使用这些参数可对模板进行一系列的修改控制。变量修改器
使用"|"和调节器名称应用修改器, 使用":"分开修改器参数。变量修改器可以组合使用,像第八句一样,实际使用中可以灵活应用。
实例3.
==================================================
example3.tpl
==================================================
模板中内定的一些函数
{*下面的这一段相当于在模板内部定义一个变量UserName*}
{assign var="UserName" value="大师兄"}
这里将显示模板内部定义的一个变量:UserName = {$UserName}
下面的这一行将显示3个checkBox:
{html_checkboxes name="CheckBox" values=$CheckName checked=$IsChecked output=$value separator="
"}
下面在这一行将显示3个radio:
{html_radioes name="RadioBox" values=$RadioName checked=$IsChecked output=$value separator="
"}
下面显示一个月,日, 年选择框:
{html_select_date}
CopyRight(C) By XiaoJun, Li 2004{mailto address="teacherli@163.ccom" text="联系作者"}
======================================================
example3.php
====================================================== template_dir = './templates/';
$smarty->compile_dir = './templates_c/';
$smarty->config_dir = './configs/';
$smarty->cache_dir = './cache/';
$smarty->caching = false;
//--------------------------------------------------------------------------------------
//处理{html_checkboxes name="CheckBox" values=$CheckName checked=$IsChecked output=$value separator="
"}
//--------------------------------------------------------------------------------------
$smarty->assign('CheckName', array(
1001 => '语文',
1002 => '数学',
1003 => '外语'));
$smarty->assign('IsChecked', 1001);
//--------------------------------------------------------------------------------------
//处理{html_radioes name="RadioBox" values=$RadioName checked=$IsChecked output=$value separator="
"}
//--------------------------------------------------------------------------------------
$smarty->assign('RadioName', array(
1001 => '语文',
1002 => '数学',
1003 => '外语'));
$smarty->assign('IsChecked', 1001);
//--------------------------------------------------------------------------------------
//{html_select_date}不用处理会自动输出
//--------------------------------------------------------------------------------------
$smarty->display("example3.tpl");
?>
the third part
======================================================
example3.php输出效果:
======================================================
模板中内定的一些函数
{assign var="UserName" value="大师兄"}
这里将显示模板内部定义的一个变量:UserName = 大师兄
下面的这一行将显示3个checkBox:
语文
数学
外语
下面在这一行将显示3个radio:
语文
数学
外语
下面显示一个月,日, 年选择框:
January
February
March
April
May
June
July
August
September
October
November
December
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2004
CopyRight(C)
By XiaoJun, Li 2004ÁªÏµ×÷Õß
例3使用了一些smarty模板中内置的一些函数,相似的函数大家可以在手册中查到,使用方法很简单,大家可以自己去查找.
例4.模板控制(if / elseif / else/ endif )
=======================================================
example4.tpl
=======================================================
模板中的流程控制
{assign var="tbColor" value="#D4D0C8"}
色彩:{$tbColor}
{section name=loop loop=$News}
{if $tbColor == "#D4D0C8"}
{assign var="tbColor" value="#EEEEEE"}
{else $tbColor == "#EEEEEE"}
{assign var="tbColor" value="#D4D0C8"}
{/if}
{$News[loop].newsID}
{$News[loop].newsTitle}
{/section}
=======================================================
example4.php
=======================================================
template_dir = './templates/';
$smarty->compile_dir = './templates_c/';
$smarty->config_dir = './configs/';
$smarty->cache_dir = './cache/';
$smarty->caching = false;
$array[]= array("newsID"=>"001", "newsTitle"=>"第1条新闻");
$array[]= array("newsID"=>"002", "newsTitle"=>"第2条新闻");
$array[]= array("newsID"=>"003", "newsTitle"=>"第3条新闻");
$array[]= array("newsID"=>"004", "newsTitle"=>"第4条新闻");
$array[]= array("newsID"=>"005", "newsTitle"=>"第5条新闻");
$array[]= array("newsID"=>"006", "newsTitle"=>"第6条新闻");
$array[]= array("newsID"=>"007", "newsTitle"=>"第7条新闻");
$array[]= array("newsID"=>"008", "newsTitle"=>"第8条新闻");
$smarty->assign("News", $array);
$smarty->display("example4.tpl");
?>the fourth part
==================================================
example4.php输出:
==================================================
模板中的流程控制
001
第1条新闻
002
第2条新闻
003
第3条新闻
004
第4条新闻
005
第5条新闻
006
第6条新闻
007
第7条新闻
008
第8条新闻
模板文件中使用: {if $tbColor == "#D4D0C8"}
{assign var="tbColor" value="#EEEEEE"}
{else $tbColor == "#EEEEEE"}
{assign var="tbColor" value="#D4D0C8"}
{/if} 这一语句块进行设置每一行的背景颜色, {assign var="tbColor" value="#D4D0C8"}还记的吧,是例3中设置模板内部变量的定义方法,
使用模板内置 的流程控制语句有时可以极大程度上提高程序的控制能力,下面一个例子是phpx.com中曾经有位朋友问过的,我将它作为
实例放在这里供大家学习.
例5: 使用模板内置流程控制语句进行一行多单元格内容输出, 也就是在视觉上smarty每记输出几条记录:
================================================
example5.tpl
================================================
一行输出多条记录
{section name=loop loop=$News step=1}
{if $smarty.section.loop.index % 4 == 0}
{/if}
{$News[loop].newsID}
{$News[loop].newsTitle}
{/section}
====================================================
example5.php
====================================================template_dir = './templates/';
$smarty->compile_dir = './templates_c/';
$smarty->config_dir = './configs/';
$smarty->cache_dir = './cache/';
$smarty->caching = false;
$array[]= array("newsID"=>"001", "newsTitle"=>"第1条新闻");
$array[]= array("newsID"=>"002", "newsTitle"=>"第2条新闻");
$array[]= array("newsID"=>"003", "newsTitle"=>"第3条新闻");
$array[]= array("newsID"=>"004", "newsTitle"=>"第4条新闻");
$array[]= array("newsID"=>"005", "newsTitle"=>"第5条新闻");
$array[]= array("newsID"=>"006", "newsTitle"=>"第6条新闻");
$array[]= array("newsID"=>"007", "newsTitle"=>"第7条新闻");
$array[]= array("newsID"=>"008", "newsTitle"=>"第8条新闻");
$smarty->assign("News", $array);
$smarty->display("example5.tpl");
?> ==================================================
example5.php输出内容:
==================================================
一行输出多条记录
001
第1条新闻
002
第2条新闻
003
第3条新闻
004
第4条新闻
005
第5条新闻
006
第6条新闻
007
第7条新闻
008
第8条新闻
说明:本来还可以优化,使得第一行不输出一个空行的 ,但是学习程序,简单为好,先就这么用了. 在这里说明一下: {section name=loop loop=$News step=1}
{if $smarty.section.loop.index % 4 == 0}
{/if}
{$News[loop].newsID}
{$News[loop].newsTitle}
{/section} {section}{/section}指的是一个循环部分,在下一节会有详细的介绍,我们主要来看看这一句:
{if $smarty.section.loop.index % 4 == 0}
$smarty.section.loop指出$smarty的实例中的section段有一个叫loop的部分, 它有一个属性叫index, 它的表示当前循环的索引值,
从0开始递增, 我们把它%4后与0相比较,也就是说,如果当前的索引值是4的倍数,它就输出一个,否则执行下面的部分,
很简单的就解决了一个在程序上实现起来很麻烦的事情.
剛開始接觸樣版引擎的 PHP 設計師,聽到 Smarty
時,都會覺得很難。其實筆者也不例外,碰都不敢碰一下。但是後來在剖析 XOOPS 的程式架構時,開始發現 Smarty 其實並不難。只要將
Smarty 基礎功練好,在一般應用上就已經相當足夠了。當然基礎能打好,後面的進階應用也就不用怕了。
這
篇文章的主要用意並非要深入探討 Smarty 的使用,這在官方使用說明中都已經寫得很完整了。筆者僅在此寫下一些自己使用上的心得,讓想要了解
Smarty 卻不得其門而入的朋友,可以從中得到一些啟示。就因為這篇文章的內容不是非常深入,會使用 Smarty 的朋友們可能會覺得簡單了點。
目
前本文已經第三次修訂了,本想多加一些料進來;不過礙於時間的關係,很多 Smarty
的進階技巧筆者並沒有研究得很透徹,所以也不敢拿出來現眼,但筆者相信這篇文章應該能夠滿足大多數想學習 Smarty
的初學者了。當然本文有謬誤的地方也歡迎告知,筆者會在下一次的修訂中更正的。
目前本文已經第四次改版了,修改與新增的內容有:
TWBB
站長 - FIEND 、
網路甘仔店
站長 - Dannis 等兩位加持。在這裡筆者由衷地感謝他們兩位的指導與建議,當然各位朋友們有任何疑惑的話,都可以到他們的網站做更詳細的討論。
-->
P.S. 請在 1024 x 768 的環境下看會比較好。
jaceju@seed.net.tw
2004/02/09
Smarty介紹
什麼是樣版引擎不知道從什麼時候開始,有人開始對 HTML 內嵌入 Server Script
覺得不太滿意。然而不論是微軟的 ASP 或是開放源碼的 PHP,都是屬於內嵌 Server Script
的網頁伺服端語言。因此也就有人想到,如果能把程式應用邏輯 (或稱商業應用邏輯) 與網頁呈現 (Layout) 邏輯分離的話,是不是會比較好呢?
其實這個問題早就存在已久,從互動式網頁開始風行時,不論是 ASP 或是 PHP
的使用者都是身兼程式開發者與視覺設計師兩種身份。可是通常這些使用者不是程式強就是美工強,如果要兩者同時兼顧,那可得死掉不少腦細胞...
所以樣版引擎就應運而生啦!樣版引擎的目的,就是要達到上述提到的邏輯分離的功能。它能讓程式開發者專注於資料的控制或是功能的達成;而視覺設計師則可專注於網頁排版,讓網頁看起來更具有專業感!因此樣版引擎很適合公司的網站開發團隊使用,使每個人都能發揮其專長!
就筆者接觸過的樣版引擎來說,依資料呈現方式大概分成:需搭配程式處理的樣版引擎和完全由樣版本身自行決定的樣版引擎兩種形式。
在
需搭配程式處理的樣版引擎中,程式開發者必須要負責變數的呈現邏輯,也就是說他必須把變數的內容在輸出到樣版前先處理好,才能做 assign
的工作。換句話說,程式開發者還是得多寫一些程式來決定變數呈現的風貌。而完全由樣版本身自行決定的樣版引擎,它允許變數直接 assign
到樣版中,讓視覺設計師在設計樣版時再決定變數要如何呈現。因此它就可能會有另一套屬於自己的樣版程式語法 (如 Smarty)
,以方便控制變數的呈現。但這樣一來,視覺設計師也得學習如何使用樣版語言。
樣版引擎的運作原理首先我們先看看以下的運作圖:
![]()
一般的樣版引擎 (如 PHPLib) 都是在建立樣版物件時取得要解析的樣版,然後把變數套入後,透過
parse() 這個方法來解析樣版,最後再將網頁輸出。
![]()
對 Smarty 的使用者來說,程式裡也不需要做任何
parse 的動作了,這些 Smarty 自動會幫我們做。而且已經編譯過的網頁,如果樣版沒有變動的話,
Smarty 就自動跳過編譯的動作,直接執行編譯過的網頁,以節省編譯的時間。
使用Smarty的一些概念在一般樣版引擎中,我們常看到區域的觀念,所謂區塊大概都會長成這樣:
區域內容
這些區塊大部份都會在 PHP 程式中以 if 或 for, while 來控制它們的顯示狀態,雖然樣版看起來簡潔多了,但只要一換了顯示方式不同的樣版,
PHP 程式勢必要再改一次!
在 Smarty 中,一切以變數為主,所有的呈現邏輯都讓樣版自行控制。因為
Smarty 會有自己的樣版語言,所以不管是區塊是否要顯示還是要重覆,都是用 Smarty 的樣版語法 (if,
foreach, section) 搭配變數內容作呈現。這樣一來感覺上好像樣版變得有點複雜,但好處是只要規劃得當,
PHP 程式一行都不必改。
由上面的說明,我們可以知道使用 Smarty 要掌握一個原則:將程式應用邏輯與網頁呈現邏輯明確地分離。就是說
PHP 程式裡不要有太多的 HTML 碼。程式中只要決定好那些變數要塞到樣版裡,讓樣版自己決定該如何呈現這些變數
(甚至不呈現也行) 。
Smarty的基礎
安裝Smarty首先,我們先決定程式放置的位置。
Windows下可能會類似這樣的位置:「 d:\appserv\web\demo\ 」。
Linux下可能會類似這樣的位置:「 /home/jaceju/public_html/ 」。
到Smarty的官方網站下載最新的Smarty套件:
http://smarty.php.net
。
解開 Smarty 2.6.0 後,會看到很多檔案,其中有個 libs 資料夾。在 libs 中應該會有
3 個 class.php 檔 + 1 個 debug.tpl + 1 個 plugin 資料夾 + 1
個 core 資料夾。然後直接將 libs 複製到您的程式主資料夾下,再更名為
class 就可以了。就這樣?沒錯!這種安裝法比較簡單,適合一般沒有自己主機的使用者。
至
於 Smarty
官方手冊中為什麼要介紹一些比較複雜的安裝方式呢?基本上依照官方的方式安裝,可以只在主機安裝一次,然後提供給該主機下所有設計者開發不同程式時直接引
用,而不會重覆安裝太多的 Smarty 複本。而筆者所提供的方式則是適合要把程式帶過來移過去的程式開發者使用,這樣不用煩惱主機有沒有安裝
Smarty 。
程式的資料夾設定以筆者在Windows安裝Appserv為例,程式的主資料夾是「d:\appserv\web\demo\」。安裝好Smarty後,我們在主資料夾下再建立這樣的資料夾:
![]()
在 Linux 底下,請記得將 templates_c 的權限變更為 777 。Windows 下則將其唯讀取消。
第一個用Smarty寫的小程式我們先設定 Smarty 的路徑,請將以下這個檔案命名為 main.php ,並放置到主資料夾下:
main.php:
// 最後沒有斜線
$tpl = new Smarty();
$tpl->template_dir = __SITE_ROOT . "/templates/";
$tpl->compile_dir = __SITE_ROOT . "/templates_c/";
$tpl->config_dir = __SITE_ROOT . "/configs/";
$tpl->cache_dir = __SITE_ROOT . "/cache/";
$tpl->left_delimiter = 'right_delimiter = '}>';
?>
照上面方式設定的用意在於,程式如果要移植到其他地方,只要改 __SITE_ROOT 就可以啦。 (這裡是參考 XOOPS 的 )
Smarty 的樣版路徑設定好後,程式會依照這個路徑來抓所有樣版的相對位置 (範例中是 'd:/appserv/web/demo/templates/' ) 。然後我們用 display() 這個 Smarty 方法來顯示我們的樣版。
接下來我們在 templates 資料夾下放置一個 test.htm:(副檔名叫什麼都無所謂,但便於視覺設計師開發,筆者都還是以 .htm 為主。)
templates/test.htm:
現在我們要將上面的樣版顯示出來,並將網頁標題 ($title) 與內容 ($content) 更換,請將以下檔案內容命名為 test.php ,並放置在主資料夾下:
test.php:
assign("title", "測試用的網頁標題");
$tpl->assign("content", "測試用的網頁內容");
// 上面兩行也可以用這行代替
// $tpl->assign(array("title" => "測試用的網頁標題", "content" => "測試用的網頁內容"));
$tpl->display('test.htm');
?>
請打開瀏覽器,輸入 http://localhost/demo/test.php 試試看(依您的環境決定網址),應該會看到以下的畫面:
![]()
再到 templates_c 底下,我們會看到一個奇怪的資料夾 (%%179) ,再點選下去也是一個奇怪的資料夾 (%%1798044067) ,而其中有一個檔案:
templates_c/%%179/%%1798044067/test.htm.php:
/* Smarty version 2.6.0, created on 2003-12-15 22:19:45 compiled from test.htm */ ?>
_tpl_vars['title']; ?>
_tpl_vars['content']; ?>
沒錯,這就是 Smarty 編譯過的檔案。它將我們在樣版中的變數轉換成了 PHP 的語法來執行,下次再讀取同樣的內容時, Smarty 就會直接抓取這個檔案來執行了。
最後我們整理一下整個 Smarty 程式撰寫步驟:
Step 1. 載入 Smarty 樣版引擎。
Step 2. 建立 Smarty 物件。
Step 3. 設定 Smarty 物件的參數。
Step 4. 在程式中處理變數後,再用 Smarty 的 assign 方法將變數置入樣版裡。
Step 5. 利用 Smarty 的 display 方法將網頁秀出。
如何安排你的程式架構上
面我們看到除了 Smarty 所需要的資料夾外 (class 、 configs 、 templates 、 templates_c)
,還有兩個資料夾: includes 、 modules 。其實這是筆者模仿 XOOPS 的架構所建立出來的,因為 XOOPS
是筆者所接觸到的程式中,少數使用 Smarty 樣版引擎的架站程式。所謂西瓜偎大邊,筆者這樣的程式架構雖沒有 XOOPS
的百分之一強,但至少給人看時還有 XOOPS 撐腰。
includes 這個資料夾主要是用來放置一些 function 、 sql 檔,這樣在 main.php 就可以將它們引入了,如下:
main.php:
// 最後沒有斜線
// 以 main.php 的位置為基準
require_once "includes/functions.php";
require_once "includes/include.php";
$tpl = new Smarty();
$tpl->template_dir = __SITE_ROOT . "/templates/";
$tpl->compile_dir = __SITE_ROOT . "/templates_c/";
$tpl->config_dir = __SITE_ROOT . "/configs/";
$tpl->cache_dir = __SITE_ROOT . "/cache/";
$tpl->left_delimiter = 'right_delimiter = '}>';
?>
modules 這個資料夾則是用來放置程式模組的,如此一來便不會把程式丟得到處都是,整體架構一目瞭然。
上
面我們也提到 main.php
,這是整個程式的主要核心,不論是常數定義、外部程式載入、共用變數建立等,都是在這裡開始的。所以之後的模組都只要將這個檔案包含進來就可以啦。因此在
程式流程規劃期間,就必須好好構思 main.php 中應該要放那些東西;當然利用 include 或 require
指令,把每個環節清楚分離是再好不過了。
![]()
在上節提到的 Smarty 程式 5 步驟, main.php 就會幫我們先將前 3 個步驟做好,後面的模組程式只要做後面兩個步驟就可以了。
從變數開始
如何使用變數從上一章範例中,我們可以清楚地看到我們利用 及 }> 這兩個標示符號將變數包起來。預設的標示符號為 { 及 }
,但為了中文衝碼及 Javascript 的關係,因此筆者還是模仿 XOOPS ,將標示符號換掉。變數的命名方式和 PHP
的變數命名方式是一模一樣的,前面也有個 $ 字號 (這和一般的樣版引擎不同)。標示符號就有點像是 PHP 中的 (事實上它們的確會被替換成這個) ,所以以下的樣版變數寫法都是可行的:
1.
2.
3.
在 Smarty 裡,變數預設是全域的,也就是說你只要指定一次就好了。指定兩次以上的話,變數內容會以最後指定的為主。就算我們在主樣版中載入了外部的子樣版,子樣版中同樣的變數一樣也會被替代,這樣我們就不用再針對子樣版再做一次解析的動作。
而
在 PHP 程式中,我們用 Smarty 的 assign 來將變數置放到樣版中。 assign
的用法官方手冊中已經寫得很多了,用法就如同上一節的範例所示。不過在重覆區塊時,我們就必須將變數做一些手腳後,才能將變數 assign
到樣版中,這在下一章再提。
修飾你的變數上面我們提到 Smarty 變數呈現的風貌是由樣版自行決定的,所以 Smarty 提供了許多修飾變數的函式。使用的方法如下:
範例如下:
好,那為什麼要讓樣版自行決定變數呈現的風貌?先看看底下的 HTML ,這是某個購物車結帳的部份畫面。
總金額:21,000 元
一般樣版引擎的樣版可能會這樣寫:
總金額:{format_total} 元
它們的 PHP 程式中要這樣寫:
assign("total", $total);
$tpl->assign("format_total", number_format($total));
?>
而 Smarty 的樣版就可以這樣寫: (number_format 修飾函式請到 Smarty 官方網頁下載)
" />
總金額: 元
Smarty 的 PHP 程式中只要這樣寫:
assign("total", $total);
?>
所以在 Smarty 中我們只要指定一次變數,剩下的交給樣版自行決定即可。這樣瞭解了嗎?這就是讓樣版自行決定變數呈現風貌的好處!
控制樣版的內容
重覆的區塊在 Smarty 樣板中,我們要重覆一個區塊有兩種方式: foreach 及 section 。而在程式中我們則要 assign 一個陣列,這個陣列中可以包含數組陣列。就像下面這個例子:
首先我們來看 PHP 程式是如何寫的:
test2.php:
"蘋果", 2 => "鳳梨", 3 => "香蕉", 4 => "芭樂");
$tpl->assign("array1", $array1);
$array2 = array(
array("index1" => "data1-1", "index2" => "data1-2", "index3" => "data1-3"),
array("index1" => "data2-1", "index2" => "data2-2", "index3" => "data2-3"),
array("index1" => "data3-1", "index2" => "data3-2", "index3" => "data3-3"),
array("index1" => "data4-1", "index2" => "data4-2", "index3" => "data4-3"),
array("index1" => "data5-1", "index2" => "data5-2", "index3" => "data5-3"));
$tpl->assign("array2", $array2);
$tpl->display("test2.htm");
?>
而樣版的寫法如下:
templates/test2.htm:
測試重覆區塊
利用 foreach 來呈現 array1
利用 section 來呈現 array1
利用 foreach 來呈現 array2
:
利用 section 來呈現 array1
index1:
index2:
index3:
執行上例後,我們發現不管是 foreach 或 section 兩個執行結果是一樣的。那麼兩者到底有何不同呢?
第
一個差別很明顯,就是 foreach 要以巢狀處理的方式來呈現我們所 assign 的兩層陣列變數,而 section
則以「主陣列[迴圈名稱].子陣列索引」即可將整個陣列呈現出來。由此可知, Smarty 在樣版中的 foreach 和 PHP 中的
foreach 是一樣的;而 section 則是 Smarty 為了處理如上列的陣列變數所發展出來的敘述。當然 section
的功能還不只如此,除了下一節所談到的巢狀資料呈現外,官方手冊中也提供了好幾個 section 的應用範例。
不過要注意的是,丟給 section 的陣列索引必須是從 0 開始的正整數,即 0, 1, 2, 3, ...。如果您的陣列索引不是從 0 開始的正整數,那麼就得改用 foreach 來呈現您的資料。您可以參考官方討論區中的
此篇討論
,其中探討了 section 和 foreach 的用法。
巢狀資料的呈現樣版引擎裡最令人傷腦筋的大概就是巢狀資料的呈現吧,許多著名的樣版引擎都會特意強調這點,不過這對 Smarty 來說卻是小兒科。
最常見到的巢狀資料,就算論譠程式中的討論主題區吧。假設要呈現的結果如下:
公告區
站務公告
文學專區
好書介紹
奇文共賞
電腦專區
硬體週邊
軟體討論
程式中我們先以靜態資料為例:
test3.php:
1, "category_name" => "公告區",
"topic" => array(
array("topic_id" => 1, "topic_name" => "站務公告")
)
),
array("category_id" => 2, "category_name" => "文學專區",
"topic" => array(
array("topic_id" => 2, "topic_name" => "好書介紹"),
array("topic_id" => 3, "topic_name" => "奇文共賞")
)
),
array("category_id" => 3, "category_name" => "電腦專區",
"topic" => array(
array("topic_id" => 4, "topic_name" => "硬體週邊"),
array("topic_id" => 5, "topic_name" => "軟體討論")
)
)
);
$tpl->assign("forum", $forum);
$tpl->display("test3.htm");
?>
樣版的寫法如下:
templates/test3.htm:
巢狀迴圈測試
執行的結果就像筆者舉的例子一樣。
因
此呢,在程式中我們只要想辦法把所要重覆值一層一層的塞到陣列中,再利用
這樣的方式來顯示每一個巢狀迴圈中的值。至於用什麼方法呢?下一節使用資料庫時我們再提。
轉換資料庫中的資料上面提到如何顯示巢狀迴圈,而實際上應用時我們的資料可能是從資料庫中抓取出來的,所以我們就得想辦法把資料庫的資料變成上述的多重陣列的形式。這裡筆者用一個 DB 類別來抓取資料庫中的資料,您可以自行用您喜歡的方法。
我們只修改 PHP 程式,樣版還是上面那個 (這就是樣版引擎的好處~),其中 $db 這個物件假設已經在 main.php 中建立好了,而且抓出來的資料就是上面的例子。
test3.php:
// 先建立第一層陣列
$category = array();
$db->setSQL($SQL1, 'CATEGORY');
if (!$db->query('CATEGORY')) die($db->error());
// 抓取第一層迴圈的資料
while ($item_category = $db->fetchAssoc('CATEGORY'))
{
// 建立第二層陣列
$topic = array();
$db->setSQL(sprintf($SQL2, $item_category['category_id']), 'TOPIC');
if (!$db->query('TOPIC')) die($db->error());
// 抓取第二層迴圈的資料
while ($item_topic = $db->fetchAssoc('TOPIC'))
{
// 把抓取的資料推入第二層陣列中
array_push($topic, $item_topic);
}
// 把第二層陣列指定為第一層陣列所抓取的資料中的一個成員
$item_category['topic'] = $topic;
// 把第一層資料推入第一層陣列中
array_push($category, $item_category);
}
$tpl->assign("forum", $category);
$tpl->display("test3.htm");
?>
在資料庫抓取一筆資料後,我們得到的是一個包含該筆資料的陣列。透過 while 敘述及 array_push 函式,我們將資料庫中的資料一筆一筆塞到陣列裡。如果您只用到單層迴圈,就把第二層迴圈 (紅色的部份) 去掉即可。
決定內容是否顯示要決定是否顯示內容,我們可以使用 if 這個語法來做選擇。例如如果使用者已經登入的話,我們的樣版就可以這樣寫:
顯示使用者操作選單
顯示輸入帳號和密碼的表單
要注意的是,「==」號兩邊一定要各留至少一個空白字元,否則 Smarty 會無法解析。
if 語法一般的應用可以參照官方使用說明,所以筆者在這裡就不詳加介紹了。不過筆者發現了一個有趣的應用:常常會看到程式裡要產生這樣的一個表格: (數字代表的是資料集的順序)
1
2
3
4
5
6
7
8
這
個筆者稱之為「橫向重覆表格」。它的特色和傳統的縱向重覆不同,前幾節我們看到的重覆表格都是從上而下,一列只有一筆資料。而橫向重覆表格則可以橫向地在
一列中產生 n 筆資料後,再換下一列,直到整個迴圈結束。要達到這樣的功能,最簡單的方式只需要 section 和 if 搭配即可。
我們來看看下面這個例子:
test4.php:
"0"),
array("value" => "1"),
array("value" => "2"),
array("value" => "3"),
array("value" => "4"),
array("value" => "5"),
array("value" => "6"),
array("value" => "7"),
array("value" => "8"),
array("value" => "9"));
$tpl->assign("my_array", $my_array);
$tpl->display('test4.htm');
?>
樣版的寫法如下:
templates/test4.htm:
橫向重覆表格測試
重點在於 $smarty.section.sec1.rownum 這個 Smarty 變數,在 section 迴圈中這個變數會取得從 1 開始的 索引值,所以當 rownum 能被 2 除盡時,就輸出 使表格換列 (注意!是 在前面 在後面) 。因此數字 2 就是我們在一列中想要呈現的資料筆數。各位可以由此去變化其他不同的呈現方式。
載入外部內容我們可以在樣版內載入 PHP 程式碼或是另一個子樣版,分別是使用 include_php 及 include 這兩個 Smarty 樣版語法; include_php 筆者較少用,使用方式可以查詢官方手冊,這裡不再敘述。
在使用 include 時,我們可以預先載入子樣版,或是動態載入子樣版。預先載入通常使用在有共同的文件標頭及版權宣告;而動態載入則可以用在統一的框架頁,而進一步達到如 Winamp 般可換 Skin 。當然這兩種我們也可以混用,視狀況而定。
我們來看看下面這個例子:
test5.php:
assign("title", "Include 測試");
$tpl->assign("content", "這是樣版 2 中的變數");
$tpl->assign("dyn_page", "test5_3.htm");
$tpl->display('test5_1.htm');
?>
樣版 1 的寫法如下:
templates/test5_1.htm:
樣版 2 的寫法如下:
templates/test5_2.htm:
樣版 3 的寫法如下:
templates/test5_3.htm:
這是樣版 3 的內容
樣版 4 的寫法如下:
templates/test5_4.htm:
這
裡注意幾個重點:1. 樣版的位置都是以先前定義的 template_dir 為基準;2. 所有 include
進來的子樣版中,其變數也會被解譯。;3. include 中可以用「變數名稱=變數內容」來指定引含進來的樣版中所包含的變數,如同上面樣版 4
的做法。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/15010/showart_260904.html |
|