ThinkPHP 3.2 模板研究

炎藤發表於2015-03-11

1. 關於 ThinkPHP 3.2 的模板引擎

ThinkPHP 內建了一個基於 XML 的編譯型模板引擎,當然你也可以使用第三方的模板引擎。

可以支援 Smarty、TemplateLite、SmartTemplate 和 EaseTemplate 等第三方模板引擎

via http://document.thinkphp.cn/manual_3_2.html#template_driver

2. 關於 ThinkPHP 3.2 的模板目錄檔案的

在 ThinkPHP 官方教程上提供了各種強大功能的設定教學,不過功能多不等於最好,最好的方法是保持預設,不做任何修改,與大部分的開發例項看齊,這樣才是最佳的,ThinkPHP 3.2.3 的預設目錄如下

www  WEB部署目錄(或者子目錄)  
├─index.php       入口檔案  
├─README.md       README檔案  
├─Application     應用目錄  
│    ├─Common
│    │  ├─Common
│    │  └─Conf
│    └─Home
│       ├─Common
│       ├─Conf
│       ├─Controller
│       ├─Model
│       └─View
│           ├─Form
│           ├─Index
│           ├─Note
│           └─User
├─Public          資原始檔目錄  
└─ThinkPHP        框架目錄  

就直接在該目錄格局下開發就好了,這是與 ThinkPHP 3.1 不同的地方,3.1 中對新人可能不太友好,每次都要建立編寫一個 index.php 檔案才行。

3. 關於 ThinkPHP 3.2 中的 __PUBLIC__ 模板素材資料夾

ThinkPHP 中的 Public 是用來存放一些模板會用到的一些素材,比如圖片、CSS、JS 檔案等,模板就是用來作為內容的排版部署,內容放資料庫,素材放 Public,這樣就把各個資源比較好的區別開。

要注意的是,ThinkPHP 3.1 中的模板是 __ROOT__ . "../Public",當前專案目錄的上一級目錄,而 ThinkPHP 3.2 下則是 __ROOT__ . "./Public",當前專案目錄,所以 ThinkPHP 3.2 在目錄結構上的部署,相對來說更規範一些。

大概有一個印象之後,我們們再深入的去了解一下刺激的部分了,下面幾個章節將分篇幅深入講解 ThinkPHP 3.2 的模板系統。

ThinkPHP 模板研究: 變數與陣列

提示 本文件部分內容未在 3.2 下進行驗證,可能與實際情況有所不符,參考來源,來自官方《[ThinkPHP模板指南][1]》

官方的《ThinkPHP模板指南》還是比較難咬一些,有點冗長磨嘰,這裡我自己總結一些比較好用的模板開發的知識點。

1. 一般變數的呼叫

ThinkPHP 支援兩種方法呼叫變數,一種是 XML 方式,比如 <var name="name">,另一種是 Smarty 方式 {$name}。這兩種寫法可以混合在一起使用,不會衝突,不過我建議還是使用 {$name} 這樣寫法,提高開發速度(雖然官方是推薦 XML 的編寫格式,比較穩定嚴謹),PHP 的目的就是為了提高開發速度,如果為了嚴謹和系統的效能,還是用 Java 吧。

模板程式碼:

<!-- ThinkPHP 3.2 -->
<!-- File: /Application/Home/View/Index/index.html -->
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8"/>
        <title>{$name}</title>
    </head>
    <body>
        {$name}
    </body>
</html>
注意 模板標籤的{和$之間不能有任何的空格,否則標籤無效。

除了在模板中要有變數呼叫的標籤,在 Action(在 ThinkPHP 3.2 版本中 Action 則用 Controller 代替) 中還要設定變數值,這裡以 Index 為例:

# ThinkPHP 3.1
# File: /app/Lib/Action/IndexAction.class.php
class IndexAction extends Action {
    public function index(){
        $this->name = "Hello world!";
        $this->display();
    }
}

ThinkPHP 3.2 版本的例子:

# ThinkPHP 3.2
# File: /Application/Home/Controller/IndexController.class.php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
    public function index(){
        $this->name = 'Hello world!';
        $this->display();
    }
}

除了 $name = 'Hello world! 這樣的寫法以外,還有 $this->assign('name', $name) 這樣的寫法,效果都是等同的。

2. 陣列與物件變數的輸出

如果輸出的資料是陣列,那麼就可以用 {$user['name']} 這樣的方式輸出;如果資料是物件,那麼就用 {$user:name} 這樣的格式,同時還有一個通用格式 {$user.name} 可以自動判斷陣列還是物件,不過就會有效能上的損耗,另外嚴謹起見,還是不要使用 . 式的呼叫方式。

提示 雖然說可以通過 config 中的 TMPL\_VAR\_IDENTITY 變數進行設定(`array` 或 `obj`)來設定固定常用的資料呼叫方式,不過這種方式依然會有效率上的損耗,除此之外,在現實的專案中,維護總是經手不同的開發人員,為了提高維護和開發效率,顯然點式呼叫法也不方便使用的。
注意 陣列是無法直接通過 $this->arr['key'] = 'value' 這樣定義後直接在模板中呼叫的,必須使用 $this->assign('arr', $arr) 來賦值,程式碼如下:
public function index(){
    $arr['key'] = 'value';
    $this->assign('arr', $arr);
}

通過控制器中的賦值之後,就可以通過模板呼叫了:

{$arr['key']}

如果要輸出多維陣列也都是可以通過這種方法輸出的,比如 {$arr['key1']['key2']},對於比較複雜的輸出方式,還可以通過 volist 來實現:

控制器程式碼:

$this->assign('arr', array('a', 'b', 'c'))

模板程式碼:

<volist name='arr' id='vo'>
   值: {$vo}<br/>
</volist>

還有二位陣列的方式

控制器程式碼:

$this->assign('arr', array('a'=>array(1,2,3)))

模板程式碼:

<volist name='arr' id='vo'>
    <volist name='vo' id='vo1'>
         值: {$vo}<br/>
    </volist>
</volist>

ThinkPHP 模板研究: 檔案呼叫篇

感覺 ThinkPHP 模板研究的篇幅有點長,所以我就拆開為上下兩篇,上一篇是變數與函式,本篇則著重將檔案的呼叫。

1. 引用檔案

可以使用Include標籤來包含外部的模板檔案,使用方法如下:

1、 使用完整檔名包含

格式:<include file="完整模板檔名" />
例如:

<include file="./Tpl/default/Public/header.html" />

這種情況下,模板檔名必須包含字尾。使用完整檔名包含的時候,特別要注意檔案包含指的是伺服器端包含,而不是包含一個URL地址,也就是說file引數的寫法是伺服器端的路徑,如果使用相對路徑的話,是基於專案的入口檔案位置。

2、包含當前模組的其他操作模板檔案

格式: 例如 匯入當前模組下面的read操作模版:

<include file="read" />

操作模板無需帶字尾。

3、 包含其他模組的操作模板

格式:

例如,包含Public模組的header操作模版:

<include file="Public:header" />

4、包含其他模板主題的模組操作模板

格式:<include file="主題名@模組名:操作名" />

例如,包含blue主題的User模組的read操作模版:

<include file="blue@User:read" />

5、 用變數控制要匯入的模版

格式:<include file="$變數名" />
例如

<include file="$tplName" />

給 $tplName 賦不同的值就可以包含不同的模板檔案,變數的值的用法和上面的用法相同。

6、使用快捷方式包含檔案

格式:{include:模板檔案規則}

其中的模板檔案規則可以使用上面提到的5種方式。

注意:由於模板解析的特點,從入口模板開始解析,如果外部模板有所更改,模板引擎並不會重新編譯模板,除非快取已經過期。如果修改了包含的外部模板檔案後,需要把模組的快取目錄清空,否則無法生效。

2. 匯入檔案

傳統方式的匯入外部JS和CSS檔案的方法是直接在模板檔案使用:

<script type='text/javascript' src='/Public/Js/Util/Array.js'>
<link rel="stylesheet" type="text/css" href="/App/Tpl/default/Public/css/style.css" />

系統提供了專門的標籤來簡化上面的匯入:

第一個是import標籤 ,匯入方式採用類似ThinkPHP的import函式的名稱空間方式,例如:

Type屬性預設是js, 所以下面的效果是相同的:

<import file="Js.Util.Array" />

還可以支援多個檔案批量匯入,例如:

<import file="Js.Util.Array,Js.Util.Date" />

匯入外部CSS檔案必須指定type屬性的值,例如:

<import type='css' file="Css.common" />

上面的方式預設的import的起始路徑是網站的Public目錄,如果需要指定其他的目錄,可以使用basepath屬性,例如:

<import file="Js.Util.Array" basepath="./Common" />

第二個是load標籤,通過檔案方式匯入當前專案的公共JS或者CSS

例如:

<load href="!-Public-!/Js/Common.js" />
<load href="!-Public-!/Css/common.css" />

在href屬性中可以使用特殊模板標籤替換,例如:

<load href="!-PUBLIC-!/Js/Common.js" />

Load標籤可以無需指定type屬性,系統會自動根據字尾自動判斷。

系統還提供了兩個標籤別名js和css 用法和load一致,例如:

<js href="!-PUBLIC-!/Js/Common.js" />
<css href="!-Public-!/Css/common.css" />

另外,系統提供了普通標籤的方式載入外部 js 和 css 檔案。

{load: !-PUBLIC-!/Js/Common.js}
{load: !-Public-!/Css/common.css }

ThinkPHP 模板研究: 功能標籤

ThinkPHP 3.1 包含一些邏輯判斷的功能標籤,這些標籤極大的方便了模板的編寫,可以不必通過 Action 也可以在模板編寫中直接實現豐富的資料計算和變化。

1. Volist標籤

Volist標籤主要用於在模板中迴圈輸出資料集或者多維陣列。

通常模型的select和findall方法返回的結果是一個二維陣列,可以直接使用volist標籤進行輸出。

在 Action 中首先對模版賦值:

$User = M('User');
$list = $User->select();
$this->assign('list',$list);

在模版定義如下,迴圈輸出使用者的編號和姓名:

<volist name="list" id="vo">
    {$vo.id}
    {$vo.name}
</volist>

Volist標籤的name屬性表示模板賦值的變數名稱,因此不可隨意在模板檔案中改變。id表示當前的迴圈變數,可以隨意指定,但確保不要和name屬性衝突,例如:

<volist name="list" id="data">
    {$data.id}
    {$data.name}
</volist>

支援輸出部分資料,例如輸出其中的第5~15條記錄

<volist name="list" id="vo" offset="5" length='10'>
    {$vo.name}
</volist>

輸出偶數記錄

<volist name="list" id="vo" mod="2" >
    <eq name="mod" value="1">{$vo.name}</eq>
</volist>

Mod 屬性還用於控制一定記錄的換行,例如:

<volist name="list" id="vo" mod="5" >
    {$vo.name}
    <eq name="mod" value="4"><br/></eq>
</volist>

輸出迴圈變數

<volist name="list" id="vo" key="k" >
    {$k}.{$vo.name}
</volist>

如果沒有指定key屬性的話,預設使用迴圈變數i,例如:

<volist name="list" id="vo" >
    {$i}.{$vo.name}
</volist>

如果要輸出陣列的索引,可以直接使用key變數,和迴圈變數不同的是,這個key是由資料本身決定,而不是迴圈控制的,例如:

<volist name="list" id="vo" >
    {$key}.{$vo.name}
</volist>

volist還有一個別名iterate,用法和volist是一樣。

1. Foreach標籤

foreach標籤也是用於迴圈輸出

<foreach name="list" item="vo" >
    {$vo.id}
    {$vo.name}
</foreach>

Foreach標籤相對比volist標籤簡潔,沒有volist標籤那麼多的功能。優勢是可以對物件進行遍歷輸出,而volist標籤通常是用於輸出陣列。

1. Switch標籤

模板引擎支援Switch標籤,格式為:

<switch name="變數" >
    <case value="值1">輸出內容1</case>
    <case value="值2">輸出內容2</case>
    <default />預設情況
</switch>

使用方法如下:

<switch name="User.level">
    <case value="1">value1</case>
    <case value="2">value2</case>
    <default />default
</switch>

其中name屬性可以使用函式以及系統變數,例如:

<switch name="Think.get.userId|abs">
    <case value="1">admin</case>
    <default />default
</switch>

對於case的value屬性可以支援多個條件的判斷,使用”|”進行分割,例如:

<switch name="Think.get.type">
    <case value="gif|png|jpg">影像格式</case>
    <default />其他格式

表示如果$_GET["type"] 是gif、png或者jpg的話,就判斷為影像格式。 也可以對case的value屬性使用變數,例如:

<switch name="User.userId">
    <case value="$adminId">admin</case>
    <case value="$memberId">member</case>
    <default />default
</switch>

使用變數方式的情況下,不再支援多個條件的同時判斷。

1. 比較標籤

模板引擎提供了豐富的判斷標籤,比較標籤的用法是:

<比較標籤 name="變數" value="值">內容</比較標籤>

系統支援的比較標籤以及所表示的含義分別是:

eq或者 equal:等於 neq 或者notequal:不等於 gt:大於 egt:大於等於 lt:小於 elt:小於等於 heq:恆等於 nheq:不恆等於

他們的用法基本是一致的,區別在於判斷的條件不同。 例如,要求name變數的值等於value就輸出,可以使用:

<eq name="name" value="value">value</eq>

或者

<equal name="name" value="value">value</equal>

也可以支援和else標籤混合使用:

<eq name="name" value="value">相等<else/>不相等</eq>

當 name變數的值大於5就輸出

<gt name="name" value="5">value</gt>

當name變數的值不小於5就輸出

<egt name="name" value="5">value</egt>

比較標籤中的變數可以支援物件的屬性或者陣列,甚至可以是系統變數:

舉例說明:

當vo物件的屬性(或者陣列,或者自動判斷)等於5就輸出

<eq name="vo.name" value="5">{$vo.name}</eq>

當vo物件的屬性等於5就輸出

<eq name="vo:name" value="5">{$vo.name}</eq>

當$vo['name']等於5就輸出

<eq name="vo['name']" value="5">{$vo.name}</eq>

而且還可以支援對變數使用函式

當vo物件的屬性值的字串長度等於5就輸出

<eq name="vo:name|strlen" value="5">{$vo.name}</eq>

變數名可以支援系統變數的方式,例如:

<eq name="Think.get.name" value="value">相等<else/>不相等</eq>

通常比較標籤的值是一個字串或者數字,如果需要使用變數,只需要在前面新增“$”標誌:

當vo物件的屬性等於$a就輸出

<eq name="vo:name" value="$a">{$vo.name}</eq>

所有的比較標籤可以統一使用compare標籤(其實所有的比較標籤都是compare標籤的別名),例如:

當name變數的值等於5就輸出

<compare name="name" value="5" type="eq">value</compare>

等效於 value

其中type屬性的值就是上面列出的比較標籤名稱

1. Range標籤

Range標籤用於判斷某個變數是否在某個範圍之內,包括in、notin和range三個標籤。

可以使用in標籤來判斷模板變數是否在某個範圍內,例如:

<in name="id" value="1,2,3" >輸出內容1</in>

如果判斷不再某個範圍內,可以使用:

<notin name="id" value="1,2,3" >輸出內容2</notin>

可以把上面兩個標籤合併成為:

<in name="id" value="1,2,3" >輸出內容1<else/>輸出內容2</in>

Value屬性的值可以使用變數,例如:

<in name="id" value="$var" >輸出內容1</in>

變數的值可以是字串或者陣列,都可以完成範圍判斷。

也可以直接使用range標籤,替換in和notin的用法:

<range name="id" value="1,2,3" type="in" >輸出內容1</range>

其中type屬性的值可以用in或者notin。 Present標籤 可以使用present標籤來判斷模板變數是否已經賦值,例如:

<present name="name">name已經賦值</present>

如果判斷沒有賦值,可以使用:

<notpresent name="name">name還沒有賦值</notpresent>

可以把上面兩個標籤合併成為:

<present name="name">name已經賦值<else /> name還沒有賦值</present>

1. Empty標籤

可以使用empty標籤判斷模板變數是否為空,例如:

<empty name="name">name為空值</empty>

如果判斷沒有賦值,可以使用:

<notempty name="name">name不為空</notempty>

可以把上面兩個標籤合併成為:

<empty name="name">name為空<else /> name不為空</empty>

3. Defined標籤

可以使用defined標籤判斷常量是否已經有定義,例如:

<defined name="NAME">NAME常量已經定義</defined>

如果判斷沒有被定義,可以使用:

<notdefined name="NAME">NAME常量未定義</notdefined>

可以把上面兩個標籤合併成為:

<defined name="NAME">NAME常量已經定義<else /> NAME常量未定義</defined>

1. IF 標籤

如果覺得上面的標籤都無法滿足條件判斷要求的話,我們還可以使用if標籤來定義複雜的條件判斷,例如:

<if condition="($name eq 1) OR ($name gt 100) "> value1
    <elseif condition="$name eq 2" />value2
    <else /> value3
</if>

在condition屬性中可以支援eq等判斷表示式 ,同上面的比較標籤,但是不支援帶有”>”、”<”等符號的用法,因為會混淆模板解析,所以下面的用法是錯誤的:

<if condition="$id < 5 "> value1
    <else /> value2
</if>

必須改成:

<if condition="$id lt 5 "> value1
    <else /> value2
</if>

除此之外,我們可以在condition屬性裡面使用php程式碼,例如:

<if condition="strtoupper($user['name']) neq 'THINKPHP' "> ThinkPHP
    <else /> other Framework
</if>

condition 屬性可以支援點語法和物件語法,例如: 自動判斷user變數是陣列還是物件

<if condition="$user.name neq 'ThinkPHP' "> ThinkPHP
    <else /> other Framework
</if>

或者知道user變數是物件

<if condition="$user:name neq 'ThinkPHP' "> ThinkPHP
    <else /> other Framework
</if>

由於 if 標籤的 condition 屬性裡面基本上使用的是 PHP 語法,儘可能使用判斷標籤和Switch標籤會更加簡潔,原則上來說,能夠用switch和比較標籤解決的儘量不用if標籤完成。因為switch和比較標籤可以使用變數調節器和系統變數。如果某些特殊的要求下面,IF標籤仍然無法滿足要求的話,可以使用原生php程式碼或者PHP標籤來直接書寫程式碼。

4. 標籤巢狀

模板引擎支援標籤的多層巢狀功能,可以對標籤庫的標籤指定可以巢狀。

系統內建的標籤中,volist(及其別名iterate)、switch、if、elseif、else、foreach、compare(包括所有的比較標籤)、(not)present、(not)empty、(not)defined等標籤都可以巢狀使用。例如:

<volist name="list" id="vo">
    <volist name="vo['sub']" id="sub">
        {$sub.name}
    </volist>
</volist>

上面的標籤可以用於輸出雙重迴圈。

預設的巢狀層次是3級,所以巢狀層次不能超過3層,如果需要更多的層次可以指定TAG_NESTED_LEVEL配置引數。

1. 使用PHP程式碼

PHP 程式碼可以和標籤在模板檔案中混合使用,可以在模板檔案裡面書寫任意的PHP語句程式碼 ,包括下面兩種方式:

第一種是使用php標籤:

<php>echo 'Hello,world!';</php>

第二種就是直接使用原始的php程式碼:

<?php echo 'Hello,world!'; ?>

但是 PHP 標籤或者 PHP 程式碼裡面就不能再使用標籤(包括普通標籤和XML標籤)了,因此下面的幾種方式都是無效的:

<php><eq name='name' value='value'>value</eq></php>

Php標籤裡面使用了eq標籤,因此無效

<php>if( {$user} != 'ThinkPHP' ) echo 'ThinkPHP' ;</php>

Php標籤裡面使用了{$user}普通標籤輸出變數 ,因此無效。

<php>if( $user.name != 'ThinkPHP' ) echo 'ThinkPHP' ;</php>

Php標籤裡面使用了$user.name 變數輸出 ,因此無效。

簡而言之,在PHP標籤裡面不能再使用PHP本身不支援的程式碼。

1. 原樣輸出

可以使用literal標籤來防止模板標籤被解析,例如:

<literal>
    <if condition="$name eq 1 "> value1
        <elseif condition="$name eq 2" />value2
        <else /> value3
    </if>
</literal>

上面的if標籤被literal標籤包含,因此if標籤裡面的內容並不會被模板引擎解析,而是保持原樣輸出。

Literal標籤可以用於頁面的JS程式碼外面,確保JS程式碼中的某些用法和模板引擎不產生混淆。

ThinkPHP 模板研究: 註釋與自定義

1. 模板註釋

模板支援註釋功能,該註釋文字在最終頁面不會顯示,僅供模板製作人員參考和識別。

格式:{/* 註釋內容 */ } 或 {// 註釋內容 }

說明:在顯示頁面的時候不會顯示模板註釋,僅供模板製作的時候參考。

注意{和註釋標記之間不能有空格。

例如:

{// 這是模板註釋內容 }

{/* 這是模板

註釋內容*/ }

模板註釋支援多行可以。模板註釋在生成編譯快取檔案後會自動刪除,這一點和Html的註釋不同。 引入標籤庫 前面我們所講述的標籤用法都是內建的標籤庫或者內建模板的用法,事實上,內建模板引擎的標籤庫是可以無限擴充套件和增加標籤的,一旦你擴充套件和使用了新的標籤庫,就必須要告訴模板當前要使用的標籤庫名稱,否則不會自動匯入,防止以後標籤庫大量擴充套件後增加解析工作量,匯入標籤庫使用tagLib標籤。

格式:

可以同時匯入多個標籤庫,用逗號分隔。

例如:

表示在當前模板檔案需要引入html標籤庫。要引入標籤庫必須確保有Html標籤庫的定義檔案和解析類庫(如何擴充套件這種方式請參考前面的標籤庫擴充套件部分)。Cx標籤庫內建匯入,無需使用taglib標籤匯入。

引入後,html標籤庫的所有標籤在當前模板頁面中都可以使用了。外部匯入的標籤庫必須使用標籤庫字首的xml標籤,避免兩個不同的標籤庫中存在同名的標籤定義,例如(假設Html標籤庫中已經有定義select和link標籤):

標籤庫使用的時候忽略大小寫,因此下面的方式一樣有效:

如果你的每個模板頁面都需要載入Html標籤庫的話,也可以通過配置直接預先載入Html標籤庫。

'TAGLIB_PRE_LOAD' => 'html' ,

如果有多個標籤庫需要預先載入的話,用逗號分隔。定義之後,每個模板頁面都可以直接使用:

而不需手動引入Html標籤庫。

假設你確信Html標籤庫無論在現在還是將來都不會和系統內建的標籤庫存在相同的標籤,那麼可以配置TAGLIB_BUILD_IN的值把Html標籤庫作為內建標籤庫引入,例如:

'TAGLIB_BUILD_IN' => 'cx,html' ,

這樣,也無需在模板檔案頁面引入Html標籤庫了,並且可以不帶字首直接使用Html標籤庫的標籤:

注意,cx標籤庫是系統內建標籤庫,不能刪除定義。

2. 修改定界符

模板檔案可以包含普通模板標籤和XML模板標籤,內建模板引擎的普通模板標籤預設以{ 和 } 作為開始和結束標識,並且在開始標記緊跟標籤的定義,如果之間有空格或者換行則被視為非模板標籤直接輸出。

例如:{$name} {$vo.name} {$vo['name']|strtoupper} 都屬於普通模板標籤

要更改普遍模板的起始標籤和結束標籤,請使用下面的配置引數:

TMPL_L_DELIM //模板引擎普通標籤開始標記

TMPL_R_DELIM //模板引擎普通標籤結束標記

例如在專案配置檔案中增加下面的配置:

'TMPL_L_DELIM'=>'<{',

'TMPL_R_DELIM'=>'}>',

普通標籤的定界符就被修改了,原來的

{$name} {$vo.name}

必須使用

<{$name}> <{$vo.name}> 才能生效了。

3. 自定義定製

普通模板標籤主要用於模板變數輸出、模板註釋和公共模板包含。如果要使用其它功能,請使用XML模板標籤,ThinkPHP包含了一個基於XML和TagLib技術的模板標籤,包含了普通模板有的功能,並且有一些方面的增強和補充,更重要的一點是新的標籤庫模板技術更加具有擴充套件性。新的TagLib標籤庫具有名稱空間功能,ThinkPHP框架內建了CX標籤庫。如果你覺得XML標籤無法在正在使用的編輯器裡面無法編輯,還可以更改XML標籤庫的起始和結束標籤,請修改下面的配置引數:

TAGLIB_BEGIN //標籤庫標籤開始標籤

TAGLIB_END //標籤庫標籤結束標記

例如在專案配置檔案中增加下面的配置:

'TAGLIB_BEGIN'=>'[',

'TAGLIB_END'=>']',

原來的

<eq name="name" value="value">相等<else/>不相等</eq>

就必須改成

[eq name="name" value="value"]相等[else/]不相等[/eq]

注意XML標籤和普通標籤的定界符不能衝突,否則會導致解析錯誤。

XML模板標籤可以用於模板變數輸出、檔案包含、模板註釋、條件控制、迴圈輸出等功能,而且完全可以自己擴充套件功能。

ThinkPHP 模板研究: 切換模板例項

學了那麼多模板研究的基礎知識,那麼現在來應用一下,本案例介紹 ThinkPHP 切換模板的辦法。其實 ThinkPHP 切換模板非常簡單,只要通過賦值 t 變數就行了,比如 t=blackwhite,例子如下:

http://localhost/ba101.net/dev_3.2.3/?t=blackwhite

當然你應該在 View 資料夾中就已經設定好相應的資料夾了,目錄形式如下

├─base
│ ├─Add
│ └─Index
└─blackwhite
└─Index

除此之外,config.php 檔案也要進行相應的修改,如下:

// 模板切換
'DEFAULT_THEME'     => 'base',
'THEME_LIST'        => 'base,blackwhite',
'TMPL_DETECT_THEME' => true
注意 這裡的風格名稱列表之間用半形逗號隔開,之間不可以有任何空格; 其實可以認為這個是一個小 Bug,逗號前後有空格才是符合寫作規範嘛。

這個時候,如果再重新返回訪問,就可以看到網站的新介面了,程式中甚至不需要通過 cookies 做任何的判斷處理,非常簡單方便。

該方法同樣適用於 ThinkPHP 3.1,感謝 ThinkPHP 開發組的艱辛努力,有點閒錢,就請捐助(http://www.thinkphp.cn/donate.html)他們吧。

ThinkPHP 模板研究: 函式的呼叫

僅僅是輸出變數並不能滿足模板輸出的需要,內建模板引擎支援對模板變數使用調節器和格式化功能,其實也就是提供函式支援,並支援多個函式同時使用。用於模板標籤的函式可以是 PHP 內建函式或者是使用者自定義函式。

{$webTitle|md5|strtoupper|substr=0,3}

編譯後的PHP程式碼就是:

<?php echo (substr(strtoupper(md5($webTitle)),0,3)); ?>

函式的使用沒有個數限制,但是可以允許配置 TMPL_DENY_FUNC_LIST 定義禁用函式列表,系統預設禁用了exit和echo函式,以防止破壞模板輸出,我們也可以增加額外的定義,例如:

TMPL_DENY_FUNC_LIST=>"echo,exit,halt"

並且還提供了在模板檔案中直接呼叫函式的快捷方法,無需通過模板變數,包括兩種方式:

1、執行方法並輸出返回值:

格式:{:function(…)}

例如,輸出U方法的返回值:

{:U('User/insert')}

編譯後的PHP程式碼是

<?php echo U('User/insert');?>

2、執行方法但不輸出:

格式:{~function(…)}

例如,呼叫say_hello函式:

{~say_hello('ThinkPHP')}

編譯後的PHP程式碼是:

<?php say_hello('ThinkPHP');?> 

ThinkPHP 模板研究: 系統變數與輸出

1. 系統變數

除了常規變數的輸出外,模板引擎還支援系統變數和系統常量、以及系統特殊變數的輸出。它們的輸出不需要事先賦值給某個模板變數。系統變數的輸出必須以$Think. 打頭,並且仍然可以支援使用函式。

1、系統變數:包括server、session、post、get、request、cookie

{$Think.server.script_name} // 輸出$_SERVER變數  
{$Think.session.session_id|md5} // 輸出$_SESSION變數  
{$Think.get.pageNumber} // 輸出$_GET變數  
{$Think.cookie.name} // 輸出$_COOKIE變數  

以上方式還可以寫成:

{$_SERVER.script_name } // 輸出$_SERVER變數  
{$_SESSION.session_id|md5 } // 輸出$_SESSION變數  
{$_GET.pageNumber } // 輸出$_GET變數  
{$_COOKIE.name } // 輸出$_COOKIE變數

支援輸出 $_SERVER、$_ENV、 $_POST、 $_GET、 $_REQUEST、$_SESSION 和 $_COOKIE 變數。後面的server、cookie、config 不區分大小寫,但是變數區分大小寫,例如 {$Think.server.script_name}{$Think.SERVER.script_name} 等效

SESSION 、COOKIE 還支援二維陣列的輸出,例如:

{$Think.CONFIG.user.user_name}  
{$Think.session.user.user_name}

2、系統常量:使用 $Think.const 輸出

{$Think.const.!-SELF-! } 
{$Think.const.MODULE_NAME}

或者直接使用

{$Think.!-SELF-!} 
{$Think.MODULE_NAME}

3、特殊變數:由 ThinkPHP 系統內部定義的常量

{$Think.version} //版本 
{$Think.now} //現在時間 
{$Think.template|basename} //模板頁面 
{$Think.LDELIM} //模板標籤起始符號 
{$Think.RDELIM} //模板標籤結束符號

4、配置引數:輸出專案的配置引數值

{$Think.config.db_charset}

輸出的值和 C('db_charset') 的返回結果是一樣的。

也可以輸出二維的配置引數,例如:

{$Think.config.user.user_name}

5、語言變數:輸出專案的當前語言定義值

{$Think.lang.page_error}

輸出的值和 L('page_error') 的返回結果是一樣的。

2. 快捷輸出

為了使得模板定義更加簡潔,系統還支援一些常用的變數輸出快捷標籤,包括:

{@var} //輸出 Session變數 和 {$Think.session.var} 等效
{#var} //輸出 Cookie變數 和 {$Think.cookie.var} 等效
{&var} //輸出 配置引數 和 {$Think.config.var} 等效
{%var} //輸出 語言變數 和 {$Think.lang.var} 等效
{.var} //輸出 GET變數 和 {$Think.get.var} 等效
{^var} //輸出 POST變數 和 {$Think.post.var} 等效
{*var} //輸出 常量 和 {$Think.const.var} 等效

如果需要輸出二維陣列,例如要輸出 $_SESSION['var1']['var2'] 的值快捷輸出可以使用 {@var1.var2} 的方式,同理 {#var1.var2} 可以輸出 $_COOKIE['var1']['var2'] 的值。

注意 快捷輸出的變數不支援函式的使用,所以下面的用法是錯誤的 `{#var|strlen}`

3. 預設值輸出

如果輸出的模板變數沒有值,但是我們需要在顯示的時候賦予一個預設值的話,可以使用default語法,格式:

{$變數|default="預設值"}

這裡的 default 不是函式,而是系統的一個語法規則,例如:

{$user.intro|default="這傢伙很懶,什麼也沒留下"}

對系統變數的輸出也可以支援預設值,例如:

{$Think.post.name|default="名稱為空"}

因為快捷輸出不支援使用函式,所以也不支援預設值,預設值支援 HTML 語法。

相關文章