一、模板简介

此文中的学习笔记部分资料是来自于thinkphp官方文档,http://document.thinkphp.cn/manual_3_2.html#template

本章的内容主要讲述了如何使用内置的模板引擎来定义模板文件,以及使用加载文件、模板布局和模板继承等高级功能。
ThinkPHP内置了一个基于XML的性能卓越的模板引擎 ThinkTemplate,这是一个专门为ThinkPHP服务的内置模板引擎。ThinkTemplate是一个使用了XML标签库技术的编译型模板引擎,支持两种类型的模板标签,使用了动态编译和缓存技术,而且支持自定义标签库。其特点包括:
支持XML标签库和普通标签的混合定义;
支持直接使用PHP代码书写;
支持文件包含;
支持多级标签嵌套;
支持布局模板功能;
一次编译多次运行,编译和运行效率非常高;
模板文件和布局模板更新,自动更新模板缓存;
系统变量无需赋值直接输出;
支持多维数组的快速输出;
支持模板变量的默认值;
支持页面代码去除Html空白;
支持变量组合调节器和格式化功能;
允许定义模板禁用函数和禁用PHP语法;
通过标签库方式扩展。
每个模板文件在执行过程中都会生成一个编译后的缓存文件,其实就是一个可以运行的PHP文件。模板缓存默认位于项目的Runtime/模块/Cache目录下面,以模板文件的md5编码作为缓存文件名保存的。如果在模板标签的使用过程中发现问题,可以尝试通过查看模板缓存文件找到问题所在。

二、模板功能测试

控制器$THINKPHP_HOME/Application/Home/Controller/TmplTestController.class.php

 <?php
namespace Home\Controller;
use Think\Controller;
class TmplTestController extends Controller {
private $templateData = array(
'name' => 'Jack Ma',
'sex' => 'Male',
'age' => 18
); private $webInfo = array(
array('id' => 1, 'name' => 'alipay'),
array('id' => 2, 'name' => 'taobao'),
array('id' => 3, 'name' => 'alibaba'),
array('id' => 4, 'name' => 'aliyun'),
array('id' => 5, 'name' => 'tmall'),
array('id' => 6, 'name' => 'aliexpress')
); private function getDataObj() {
//下面一行如果不在stdClass前面加上\,则会报错Class 'Home\Controller\stdClass' not found
$obj = new \stdClass();
$obj->name = 'Jack Ma';
$obj->sex = 'Male';
$obj->age = 18; return $obj;
} //http://localhost:81/research/thinkphp_3.2.3_full/index.php/Home/TmplTest/show1
public function show1() { $this->assign($this->templateData); $this->display('TmplTest:show');
/*
$this->display()相当于$this->display('TmplTest:show');
*/
} //http://localhost:81/research/thinkphp_3.2.3_full/index.php/Home/TmplTest/show2
//传递数组到模板中
public function show2() { $this->assign('data2', $this->templateData); $this->display('TmplTest:show');
} //http://localhost:81/research/thinkphp_3.2.3_full/index.php/Home/TmplTest/show3
//传递对象到模板中
public function show3() { $this->assign('data3', $this->getDataObj()); $this->display('TmplTest:show');
} //http://localhost:81/research/thinkphp_3.2.3_full/index.php/Home/TmplTest/show4
//输出系统变量
public function show4() { $this->assign('data4', $this->getDataObj()); $this->display('TmplTest:show');
} //http://localhost:81/research/thinkphp_3.2.3_full/index.php/Home/TmplTest/show5
//使用函数
public function show5() { $this->assign('data5', $this->templateData); $this->display('TmplTest:show');
} //http://localhost:81/research/thinkphp_3.2.3_full/index.php/Home/TmplTest/show6
//默认值输出
public function show6() { $this->assign('data6', $this->templateData); $this->display('TmplTest:show');
} //http://localhost:81/research/thinkphp_3.2.3_full/index.php/Home/TmplTest/show7
//默认值输出
public function show7() { $this->assign(array(
'data7' => $this->webInfo,
'tempData' => $this->templateData
)); $this->assign('empty','<strong>没有数据</strong>'); $this->display('TmplTest:show'); echo "<hr>";
debug_print_backtrace();
var_dump(get_included_files());
echo "<hr>";
}
}
?>

模板

$THINKPHP_HOME/Application/Home/View/TmplTest/show.html

 {/*
2016-5-25 加入<taglib name="html" />的时候报如下的错误,暂时不知道为什么,在网上也没有找到解决方案 XML标签语法错误
*/} 在模板中包括文件<br />
<include file="./Application/Home/View/TmplTest/header.html" title="template test" keywords="php thinkphp" />
{/* 模板中包含文件时,如果传递变量到子模板中,则子模板中的变量采用[变量名],如[title] */} name: <strong>{$name}</strong><br />
sex: <strong>{$sex}</strong><br />
age: <strong>{$age}</strong><br /><br /> 传递数组到模板中<br />
name: <strong>{$data2.name}</strong><br />
sex: <strong>{$data2['sex']}</strong><br />
age: <strong>{$data2.age}</strong><br /><br /> 传递对象到模板中<br />
name: <strong>{$data3:name}</strong><br />
sex: <strong>{$data3->sex}</strong><br />
age: <strong>{$data3:age}</strong><br /><br /> 输出系统变量<br />
{$Think.server.script_name} // 输出$_SERVER['SCRIPT_NAME']变量
<br /><br /> 常用输出<br />
{$Think.MODULE_NAME}<br /><br /> 配置输出<br />
{$Think.config.db_charset}<br />
{$Think.config.url_model}<br /><br /> 语言变量<br />
{$Think.lang.page_error}<br />
{$Think.lang.var_error}<br /><br /> 使用函数<br />
{$data5.name|md5} <br />
{$data5.name|substr=0,3}<br />
{/* 还可以支持多个函数过滤,多个函数之间用“|”分割即可 */}
{$data5.name|md5|strtoupper|substr=0,3}<br /><br /> 默认值输出<br />
{$data6.company|default="变量为空,设置它为淘宝网"}<br />
{/* 下面一行执行的时候报错'Can't use function return value in write context', http://www.cnblogs.com/taohaoge/p/4218835.html, http://www.thinkphp.cn/topic/10896.html */}
{/* $data6.company|getCompany|default="变量为空,设置它为淘宝网" */}<br /><br /> 循环输出数据<br />
{/* name表示控制器中传递给模板的变量[$this->assign('data7', $this->webInfo);], id表示当前的循环变量 */}
{/* 如果要输出数组的索引,可以直接使用key变量,和循环变量不同的是,这个key是由数据本身决定,而不是循环控制的 */}
<volist name="data7" id="data" key="k">
{$k} : {$key} : {$data.id} : {$data.name}<br />
</volist>
<br /><br /> 显示第2到4条记录,第2条记录的索引(offset)为1<br />
<volist name="data7" id="data" offset="1" length="3">
{$data.id}:{$data.name}<br />
</volist>
<br /><br /> 输出偶数记录, 如果没有指定key属性的话,默认使用循环变量i<br />
<volist name="data7" id="data" mod="2">
<eq name="mod" value="1">i:{$i} : {$data.id}:{$data.name}</eq><br />
</volist>
<br /><br /> empty功能测试<br />
<volist name="data777" id="data" empty="$empty">
{$data.id}:{$data.name}<br />
</volist>
<br /><br /> foreach标签类似与volist标签,只是更加简单,没有太多额外的属性,例如: {$vo.id}:{$vo.name}, foreach更适合关联数组<br />
<foreach name="data7" item="info">
<if condition="intval($key) lt 4"><font color="red"><strong>{$key}</strong></font><else />{$key}</if> : <php>var_dump($info);</php><br />
<volist name="info" id="subInfo">
<font color='blue'>
{$key} : {$subInfo}</font><br />
</volist>
</foreach>
<br /><br /> <foreach name="tempData" item="info">
{$key} : {$info}<br />
</foreach>
<br /><br /> 原样输出<br />
<literal>
<if condition="$name eq 1 "> value1
<elseif condition="$name eq 2"/>value2
<else /> value3
</if>
</literal>
<br /><br /> 如果你的php标签中需要输出类似{$user} 或者 XML标签的情况,可以通过添加literal标签解决混淆问题,例如:<br />
<php>echo '{$Think.config.CUSTOM}';</php>
这个php标签中的{ $Think 可能会被模板引擎误当做标签解析,解决的办法就是加上literal,例如:<br />
<php><literal>echo '{$Think.config.CUSTOM.'.$key.'}';</literal></php>
<br /><br /> 第一个是import标签 ,导入方式采用类似ThinkPHP的import函数的命名空间方式,例如:<br />
<import type='js' file="Js.Util.Array" /> 还可以支持多个文件批量导入,例如:<br />
<import file="Js.Util.Array,Js.Util.Date" /> 导入外部CSS文件必须指定type属性的值,例如:<br />
<import type='css' file="Css.common" /> 上面的方式默认的import的起始路径是网站的Public目录,如果需要指定其他的目录,可以使用basepath属性,例如:<br />
<import file="Js.Util.Array" basepath="./Common" />
<br /><br /> DEFINE标签用于中模板中定义常量,用法如下:<br />
<define name="COMPUTER_LANGUAGE" value="PHP" />
computer_language: <php>echo COMPUTER_LANGUAGE; </php><br />
<br /><br /> 在模板中包括文件<br />
<include file="./Application/Home/View/TmplTest/footer.html" /> {/*
q: <include file="Public:header" /> 在3.2 到底是指那里啊? a: view/public/header.html http://www.thinkphp.cn/topic/28371.html
*/}
<include file="Public/footer" />

$THINKPHP_HOME/Application/Home/View/TmplTest/header.html

 <html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>[title]</title>
<meta name="keywords" content="[keywords]" />
</head>
this is header template
<hr><br>

$THINKPHP_HOME/Application/Home/View/TmplTest/footer.html

 <hr><br>
this is footer template

$THINKPHP_HOME/Application/Home/View/Public/footer.html

 <hr><br>
this is footer template of directory public

模板编译缓存
$THINKPHP_HOME/Application/Runtime/Cache/Home/1919bd3bcef9744a44c09aa7f7094dfa.php

 <?php if (!defined('THINK_PATH')) exit();?>

 在模板中包括文件<br />
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>template test</title>
<meta name="keywords" content="php thinkphp" />
</head>
this is header template
<hr><br> name: <strong><?php echo ($name); ?></strong><br />
sex: <strong><?php echo ($sex); ?></strong><br />
age: <strong><?php echo ($age); ?></strong><br /><br /> 传递数组到模板中<br />
name: <strong><?php echo ($data2["name"]); ?></strong><br />
sex: <strong><?php echo ($data2['sex']); ?></strong><br />
age: <strong><?php echo ($data2["age"]); ?></strong><br /><br /> 传递对象到模板中<br />
name: <strong><?php echo ($data3->name); ?></strong><br />
sex: <strong><?php echo ($data3->sex); ?></strong><br />
age: <strong><?php echo ($data3->age); ?></strong><br /><br /> 输出系统变量<br />
<?php echo ($_SERVER['SCRIPT_NAME']); ?> // 输出$_SERVER['SCRIPT_NAME']变量
<br /><br /> 常用输出<br />
<?php echo (MODULE_NAME); ?><br /><br /> 配置输出<br />
<?php echo (C("db_charset")); ?><br />
<?php echo (C("url_model")); ?><br /><br /> 语言变量<br />
<?php echo (L("page_error")); ?><br />
<?php echo (L("var_error")); ?><br /><br /> 使用函数<br />
<?php echo (md5($data5["name"])); ?> <br />
<?php echo (substr($data5["name"],0,3)); ?><br /> <?php echo (substr(strtoupper(md5($data5["name"])),0,3)); ?><br /><br /> 默认值输出<br />
<?php echo ((isset($data6["company"]) && ($data6["company"] !== ""))?($data6["company"]):"变量为空,设置它为淘宝网"); ?><br /> <br /><br /> 循环输出数据<br /> <?php if(is_array($data7)): $k = 0; $__LIST__ = $data7;if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$data): $mod = ($k % 2 );++$k; echo ($k); ?> : <?php echo ($key); ?> : <?php echo ($data["id"]); ?> : <?php echo ($data["name"]); ?><br /><?php endforeach; endif; else: echo "" ;endif; ?>
<br /><br /> 显示第2到4条记录,第2条记录的索引(offset)为1<br />
<?php if(is_array($data7)): $i = 0; $__LIST__ = array_slice($data7,1,3,true);if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$data): $mod = ($i % 2 );++$i; echo ($data["id"]); ?>:<?php echo ($data["name"]); ?><br /><?php endforeach; endif; else: echo "" ;endif; ?>
<br /><br /> 输出偶数记录, 如果没有指定key属性的话,默认使用循环变量i<br />
<?php if(is_array($data7)): $i = 0; $__LIST__ = $data7;if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$data): $mod = ($i % 2 );++$i; if(($mod) == "1"): ?>i:<?php echo ($i); ?> : <?php echo ($data["id"]); ?>:<?php echo ($data["name"]); endif; ?><br /><?php endforeach; endif; else: echo "" ;endif; ?>
<br /><br /> empty功能测试<br />
<?php if(is_array($data777)): $i = 0; $__LIST__ = $data777;if( count($__LIST__)==0 ) : echo "$empty" ;else: foreach($__LIST__ as $key=>$data): $mod = ($i % 2 );++$i; echo ($data["id"]); ?>:<?php echo ($data["name"]); ?><br /><?php endforeach; endif; else: echo "$empty" ;endif; ?>
<br /><br /> foreach标签类似与volist标签,只是更加简单,没有太多额外的属性,例如: <?php echo ($vo["id"]); ?>:<?php echo ($vo["name"]); ?>, foreach更适合关联数组<br />
<?php if(is_array($data7)): foreach($data7 as $key=>$info): if(intval($key) < 4): ?><font color="red"><strong><?php echo ($key); ?></strong></font><?php else: echo ($key); endif; ?> : <?php var_dump($info); ?><br />
<?php if(is_array($info)): $i = 0; $__LIST__ = $info;if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$subInfo): $mod = ($i % 2 );++$i;?><font color='blue'>
<?php echo ($key); ?> : <?php echo ($subInfo); ?></font><br /><?php endforeach; endif; else: echo "" ;endif; endforeach; endif; ?>
<br /><br /> <?php if(is_array($tempData)): foreach($tempData as $key=>$info): echo ($key); ?> : <?php echo ($info); ?><br /><?php endforeach; endif; ?>
<br /><br /> 原样输出<br /> <if condition="$name eq 1 "> value1
<elseif condition="$name eq 2"/>value2
<else /> value3
</if> <br /><br /> 如果你的php标签中需要输出类似<?php echo ($user); ?> 或者 XML标签的情况,可以通过添加literal标签解决混淆问题,例如:<br />
<?php echo '<?php echo (C("CUSTOM")); ?>'; ?>
这个php标签中的{ $Think 可能会被模板引擎误当做标签解析,解决的办法就是加上literal,例如:<br />
<?php echo '{$Think.config.CUSTOM.'.$key.'}'; ?>
<br /><br /> 第一个是import标签 ,导入方式采用类似ThinkPHP的import函数的命名空间方式,例如:<br />
<script type="text/javascript" src="/research/thinkphp_3.2.3_full/Public/Js/Util/Array.js"></script> 还可以支持多个文件批量导入,例如:<br />
<script type="text/javascript" src="/research/thinkphp_3.2.3_full/Public/Js/Util/Array.js"></script><script type="text/javascript" src="/research/thinkphp_3.2.3_full/Public/Js/Util/Date.js"></script> 导入外部CSS文件必须指定type属性的值,例如:<br />
<link rel="stylesheet" type="text/css" href="/research/thinkphp_3.2.3_full/Public/Css/common.css" /> 上面的方式默认的import的起始路径是网站的Public目录,如果需要指定其他的目录,可以使用basepath属性,例如:<br />
<script type="text/javascript" src="./Common/Js/Util/Array.js"></script>
<br /><br /> DEFINE标签用于中模板中定义常量,用法如下:<br />
<?php define('COMPUTER_LANGUAGE', 'PHP'); ?>
computer_language: <?php echo COMPUTER_LANGUAGE; ?><br />
<br /><br /> 在模板中包括文件<br />
<hr><br>
this is footer template <hr><br>
this is footer template of directory public

将X从1到7循环执行,也就是说执行7次请求分别进行测试,我这里主要是为了测试方便所以分成了7次执行,一般的正式项目会一次请求输出全部的结果。
http://localhost:81/research/thinkphp_3.2.3_full/index.php/Home/TmplTest/showX

模板的输出结果如下:
在模板中包括文件
this is header template

name: Jack Ma
sex: Male
age: 18

传递数组到模板中
name: Jack Ma
sex: Male
age: 18

传递对象到模板中
name: Jack Ma
sex: Male
age: 18

输出系统变量
/research/thinkphp_3.2.3_full/index.php // 输出$_SERVER['SCRIPT_NAME']变量

常用输出
Home

配置输出
utf8
1

语言变量
PAGE_ERROR
VAR_ERROR

使用函数
422cbcaedaff825c7503f57292f81b77
Jac
422

默认值输出
变量为空,设置它为淘宝网

循环输出数据
1 : 0 : 1 : alipay
2 : 1 : 2 : taobao
3 : 2 : 3 : alibaba
4 : 3 : 4 : aliyun
5 : 4 : 5 : tmall
6 : 5 : 6 : aliexpress

显示第2到4条记录,第2条记录的索引(offset)为1
2:taobao
3:alibaba
4:aliyun

输出偶数记录, 如果没有指定key属性的话,默认使用循环变量i

i:2 : 2:taobao

i:4 : 4:aliyun

i:6 : 6:aliexpress

empty功能测试
没有数据

foreach标签类似与volist标签,只是更加简单,没有太多额外的属性,例如: :, foreach更适合关联数组
0 : array(2) { ["id"]=> int(1) ["name"]=> string(6) "alipay" }
id : 1
name : alipay
1 : array(2) { ["id"]=> int(2) ["name"]=> string(6) "taobao" }
id : 2
name : taobao
2 : array(2) { ["id"]=> int(3) ["name"]=> string(7) "alibaba" }
id : 3
name : alibaba
3 : array(2) { ["id"]=> int(4) ["name"]=> string(6) "aliyun" }
id : 4
name : aliyun
4 : array(2) { ["id"]=> int(5) ["name"]=> string(5) "tmall" }
id : 5
name : tmall
5 : array(2) { ["id"]=> int(6) ["name"]=> string(10) "aliexpress" }
id : 6
name : aliexpress

name : Jack Ma
sex : Male
age : 18

原样输出
value1 value2 value3

如果你的php标签中需要输出类似 或者 XML标签的情况,可以通过添加literal标签解决混淆问题,例如:
这个php标签中的{ $Think 可能会被模板引擎误当做标签解析,解决的办法就是加上literal,例如:
{$Think.config.CUSTOM.age}

第一个是import标签 ,导入方式采用类似ThinkPHP的import函数的命名空间方式,例如:
还可以支持多个文件批量导入,例如:
导入外部CSS文件必须指定type属性的值,例如:
上面的方式默认的import的起始路径是网站的Public目录,如果需要指定其他的目录,可以使用basepath属性,例如:

DEFINE标签用于中模板中定义常量,用法如下:
computer_language: PHP

在模板中包括文件

this is footer template

this is footer template of directory public

05-28 00:39