一、模板简介
此文中的学习笔记部分资料是来自于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
1 <?php 2 namespace HomeController; 3 use ThinkController; 4 class TmplTestController extends Controller { 5 private $templateData = array( 6 'name' => 'Jack Ma', 7 'sex' => 'Male', 8 'age' => 18 9 ); 10 11 private $webInfo = array( 12 array('id' => 1, 'name' => 'alipay'), 13 array('id' => 2, 'name' => 'taobao'), 14 array('id' => 3, 'name' => 'alibaba'), 15 array('id' => 4, 'name' => 'aliyun'), 16 array('id' => 5, 'name' => 'tmall'), 17 array('id' => 6, 'name' => 'aliexpress') 18 ); 19 20 private function getDataObj() { 21 //下面一行如果不在stdClass前面加上,则会报错Class 'HomeControllerstdClass' not found 22 $obj = new stdClass(); 23 $obj->name = 'Jack Ma'; 24 $obj->sex = 'Male'; 25 $obj->age = 18; 26 27 return $obj; 28 } 29 30 //http://localhost:81/research/thinkphp_3.2.3_full/index.php/Home/TmplTest/show1 31 public function show1() { 32 33 $this->assign($this->templateData); 34 35 $this->display('TmplTest:show'); 36 /* 37 $this->display()相当于$this->display('TmplTest:show'); 38 */ 39 } 40 41 //http://localhost:81/research/thinkphp_3.2.3_full/index.php/Home/TmplTest/show2 42 //传递数组到模板中 43 public function show2() { 44 45 $this->assign('data2', $this->templateData); 46 47 $this->display('TmplTest:show'); 48 } 49 50 //http://localhost:81/research/thinkphp_3.2.3_full/index.php/Home/TmplTest/show3 51 //传递对象到模板中 52 public function show3() { 53 54 $this->assign('data3', $this->getDataObj()); 55 56 $this->display('TmplTest:show'); 57 } 58 59 //http://localhost:81/research/thinkphp_3.2.3_full/index.php/Home/TmplTest/show4 60 //输出系统变量 61 public function show4() { 62 63 $this->assign('data4', $this->getDataObj()); 64 65 $this->display('TmplTest:show'); 66 } 67 68 //http://localhost:81/research/thinkphp_3.2.3_full/index.php/Home/TmplTest/show5 69 //使用函数 70 public function show5() { 71 72 $this->assign('data5', $this->templateData); 73 74 $this->display('TmplTest:show'); 75 } 76 77 //http://localhost:81/research/thinkphp_3.2.3_full/index.php/Home/TmplTest/show6 78 //默认值输出 79 public function show6() { 80 81 $this->assign('data6', $this->templateData); 82 83 $this->display('TmplTest:show'); 84 } 85 86 //http://localhost:81/research/thinkphp_3.2.3_full/index.php/Home/TmplTest/show7 87 //默认值输出 88 public function show7() { 89 90 $this->assign(array( 91 'data7' => $this->webInfo, 92 'tempData' => $this->templateData 93 )); 94 95 $this->assign('empty','<strong>没有数据</strong>'); 96 97 $this->display('TmplTest:show'); 98 99 echo "<hr>"; 100 debug_print_backtrace(); 101 var_dump(get_included_files()); 102 echo "<hr>"; 103 } 104 } 105 ?>
模板
$THINKPHP_HOME/Application/Home/View/TmplTest/show.html
1 {/* 2 2016-5-25 加入<taglib name="html" />的时候报如下的错误,暂时不知道为什么,在网上也没有找到解决方案 3 4 XML标签语法错误 5 */} 6 7 在模板中包括文件<br /> 8 <include file="./Application/Home/View/TmplTest/header.html" title="template test" keywords="php thinkphp" /> 9 {/* 模板中包含文件时,如果传递变量到子模板中,则子模板中的变量采用[变量名],如[title] */} 10 11 name: <strong>{$name}</strong><br /> 12 sex: <strong>{$sex}</strong><br /> 13 age: <strong>{$age}</strong><br /><br /> 14 15 传递数组到模板中<br /> 16 name: <strong>{$data2.name}</strong><br /> 17 sex: <strong>{$data2['sex']}</strong><br /> 18 age: <strong>{$data2.age}</strong><br /><br /> 19 20 传递对象到模板中<br /> 21 name: <strong>{$data3:name}</strong><br /> 22 sex: <strong>{$data3->sex}</strong><br /> 23 age: <strong>{$data3:age}</strong><br /><br /> 24 25 输出系统变量<br /> 26 {$Think.server.script_name} // 输出$_SERVER['SCRIPT_NAME']变量 27 <br /><br /> 28 29 常用输出<br /> 30 {$Think.MODULE_NAME}<br /><br /> 31 32 配置输出<br /> 33 {$Think.config.db_charset}<br /> 34 {$Think.config.url_model}<br /><br /> 35 36 语言变量<br /> 37 {$Think.lang.page_error}<br /> 38 {$Think.lang.var_error}<br /><br /> 39 40 使用函数<br /> 41 {$data5.name|md5} <br /> 42 {$data5.name|substr=0,3}<br /> 43 {/* 还可以支持多个函数过滤,多个函数之间用“|”分割即可 */} 44 {$data5.name|md5|strtoupper|substr=0,3}<br /><br /> 45 46 默认值输出<br /> 47 {$data6.company|default="变量为空,设置它为淘宝网"}<br /> 48 {/* 下面一行执行的时候报错'Can't use function return value in write context', http://www.cnblogs.com/taohaoge/p/4218835.html, http://www.thinkphp.cn/topic/10896.html */} 49 {/* $data6.company|getCompany|default="变量为空,设置它为淘宝网" */}<br /><br /> 50 51 循环输出数据<br /> 52 {/* name表示控制器中传递给模板的变量[$this->assign('data7', $this->webInfo);], id表示当前的循环变量 */} 53 {/* 如果要输出数组的索引,可以直接使用key变量,和循环变量不同的是,这个key是由数据本身决定,而不是循环控制的 */} 54 <volist name="data7" id="data" key="k"> 55 {$k} : {$key} : {$data.id} : {$data.name}<br /> 56 </volist> 57 <br /><br /> 58 59 显示第2到4条记录,第2条记录的索引(offset)为1<br /> 60 <volist name="data7" id="data" offset="1" length="3"> 61 {$data.id}:{$data.name}<br /> 62 </volist> 63 <br /><br /> 64 65 输出偶数记录, 如果没有指定key属性的话,默认使用循环变量i<br /> 66 <volist name="data7" id="data" mod="2"> 67 <eq name="mod" value="1">i:{$i} : {$data.id}:{$data.name}</eq><br /> 68 </volist> 69 <br /><br /> 70 71 empty功能测试<br /> 72 <volist name="data777" id="data" empty="$empty"> 73 {$data.id}:{$data.name}<br /> 74 </volist> 75 <br /><br /> 76 77 foreach标签类似与volist标签,只是更加简单,没有太多额外的属性,例如: {$vo.id}:{$vo.name}, foreach更适合关联数组<br /> 78 <foreach name="data7" item="info"> 79 <if condition="intval($key) lt 4"><font color="red"><strong>{$key}</strong></font><else />{$key}</if> : <php>var_dump($info);</php><br /> 80 <volist name="info" id="subInfo"> 81 <font color='blue'> 82 {$key} : {$subInfo}</font><br /> 83 </volist> 84 </foreach> 85 <br /><br /> 86 87 <foreach name="tempData" item="info"> 88 {$key} : {$info}<br /> 89 </foreach> 90 <br /><br /> 91 92 原样输出<br /> 93 <literal> 94 <if condition="$name eq 1 "> value1 95 <elseif condition="$name eq 2"/>value2 96 <else /> value3 97 </if> 98 </literal> 99 <br /><br /> 100 101 如果你的php标签中需要输出类似{$user} 或者 XML标签的情况,可以通过添加literal标签解决混淆问题,例如:<br /> 102 <php>echo '{$Think.config.CUSTOM}';</php> 103 这个php标签中的{ $Think 可能会被模板引擎误当做标签解析,解决的办法就是加上literal,例如:<br /> 104 <php><literal>echo '{$Think.config.CUSTOM.'.$key.'}';</literal></php> 105 <br /><br /> 106 107 第一个是import标签 ,导入方式采用类似ThinkPHP的import函数的命名空间方式,例如:<br /> 108 <import type='js' file="Js.Util.Array" /> 109 110 还可以支持多个文件批量导入,例如:<br /> 111 <import file="Js.Util.Array,Js.Util.Date" /> 112 113 导入外部CSS文件必须指定type属性的值,例如:<br /> 114 <import type='css' file="Css.common" /> 115 116 上面的方式默认的import的起始路径是网站的Public目录,如果需要指定其他的目录,可以使用basepath属性,例如:<br /> 117 <import file="Js.Util.Array" basepath="./Common" /> 118 <br /><br /> 119 120 DEFINE标签用于中模板中定义常量,用法如下:<br /> 121 <define name="COMPUTER_LANGUAGE" value="PHP" /> 122 computer_language: <php>echo COMPUTER_LANGUAGE; </php><br /> 123 <br /><br /> 124 125 在模板中包括文件<br /> 126 <include file="./Application/Home/View/TmplTest/footer.html" /> 127 128 {/* 129 q: <include file="Public:header" /> 在3.2 到底是指那里啊? 130 131 a: view/public/header.html 132 133 http://www.thinkphp.cn/topic/28371.html 134 */} 135 <include file="Public/footer" />
$THINKPHP_HOME/Application/Home/View/TmplTest/header.html
1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 <head> 3 <title>[title]</title> 4 <meta name="keywords" content="[keywords]" /> 5 </head> 6 this is header template 7 <hr><br>
$THINKPHP_HOME/Application/Home/View/TmplTest/footer.html
1 <hr><br> 2 this is footer template
$THINKPHP_HOME/Application/Home/View/Public/footer.html
1 <hr><br> 2 this is footer template of directory public
模板编译缓存
$THINKPHP_HOME/Application/Runtime/Cache/Home/1919bd3bcef9744a44c09aa7f7094dfa.php
1 <?php if (!defined('THINK_PATH')) exit();?> 2 3 在模板中包括文件<br /> 4 <html xmlns="http://www.w3.org/1999/xhtml"> 5 <head> 6 <title>template test</title> 7 <meta name="keywords" content="php thinkphp" /> 8 </head> 9 this is header template 10 <hr><br> 11 12 13 name: <strong><?php echo ($name); ?></strong><br /> 14 sex: <strong><?php echo ($sex); ?></strong><br /> 15 age: <strong><?php echo ($age); ?></strong><br /><br /> 16 17 传递数组到模板中<br /> 18 name: <strong><?php echo ($data2["name"]); ?></strong><br /> 19 sex: <strong><?php echo ($data2['sex']); ?></strong><br /> 20 age: <strong><?php echo ($data2["age"]); ?></strong><br /><br /> 21 22 传递对象到模板中<br /> 23 name: <strong><?php echo ($data3->name); ?></strong><br /> 24 sex: <strong><?php echo ($data3->sex); ?></strong><br /> 25 age: <strong><?php echo ($data3->age); ?></strong><br /><br /> 26 27 输出系统变量<br /> 28 <?php echo ($_SERVER['SCRIPT_NAME']); ?> // 输出$_SERVER['SCRIPT_NAME']变量 29 <br /><br /> 30 31 常用输出<br /> 32 <?php echo (MODULE_NAME); ?><br /><br /> 33 34 配置输出<br /> 35 <?php echo (C("db_charset")); ?><br /> 36 <?php echo (C("url_model")); ?><br /><br /> 37 38 语言变量<br /> 39 <?php echo (L("page_error")); ?><br /> 40 <?php echo (L("var_error")); ?><br /><br /> 41 42 使用函数<br /> 43 <?php echo (md5($data5["name"])); ?> <br /> 44 <?php echo (substr($data5["name"],0,3)); ?><br /> 45 46 <?php echo (substr(strtoupper(md5($data5["name"])),0,3)); ?><br /><br /> 47 48 默认值输出<br /> 49 <?php echo ((isset($data6["company"]) && ($data6["company"] !== ""))?($data6["company"]):"变量为空,设置它为淘宝网"); ?><br /> 50 51 <br /><br /> 52 53 循环输出数据<br /> 54 55 56 <?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; ?> 57 <br /><br /> 58 59 显示第2到4条记录,第2条记录的索引(offset)为1<br /> 60 <?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; ?> 61 <br /><br /> 62 63 输出偶数记录, 如果没有指定key属性的话,默认使用循环变量i<br /> 64 <?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; ?> 65 <br /><br /> 66 67 empty功能测试<br /> 68 <?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; ?> 69 <br /><br /> 70 71 foreach标签类似与volist标签,只是更加简单,没有太多额外的属性,例如: <?php echo ($vo["id"]); ?>:<?php echo ($vo["name"]); ?>, foreach更适合关联数组<br /> 72 <?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 /> 73 <?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'> 74 <?php echo ($key); ?> : <?php echo ($subInfo); ?></font><br /><?php endforeach; endif; else: echo "" ;endif; endforeach; endif; ?> 75 <br /><br /> 76 77 <?php if(is_array($tempData)): foreach($tempData as $key=>$info): echo ($key); ?> : <?php echo ($info); ?><br /><?php endforeach; endif; ?> 78 <br /><br /> 79 80 原样输出<br /> 81 82 <if condition="$name eq 1 "> value1 83 <elseif condition="$name eq 2"/>value2 84 <else /> value3 85 </if> 86 87 <br /><br /> 88 89 如果你的php标签中需要输出类似<?php echo ($user); ?> 或者 XML标签的情况,可以通过添加literal标签解决混淆问题,例如:<br /> 90 <?php echo '<?php echo (C("CUSTOM")); ?>'; ?> 91 这个php标签中的{ $Think 可能会被模板引擎误当做标签解析,解决的办法就是加上literal,例如:<br /> 92 <?php echo '{$Think.config.CUSTOM.'.$key.'}'; ?> 93 <br /><br /> 94 95 第一个是import标签 ,导入方式采用类似ThinkPHP的import函数的命名空间方式,例如:<br /> 96 <script type="text/javascript" src="/research/thinkphp_3.2.3_full/Public/Js/Util/Array.js"></script> 97 98 还可以支持多个文件批量导入,例如:<br /> 99 <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> 100 101 导入外部CSS文件必须指定type属性的值,例如:<br /> 102 <link rel="stylesheet" type="text/css" href="/research/thinkphp_3.2.3_full/Public/Css/common.css" /> 103 104 上面的方式默认的import的起始路径是网站的Public目录,如果需要指定其他的目录,可以使用basepath属性,例如:<br /> 105 <script type="text/javascript" src="./Common/Js/Util/Array.js"></script> 106 <br /><br /> 107 108 DEFINE标签用于中模板中定义常量,用法如下:<br /> 109 <?php define('COMPUTER_LANGUAGE', 'PHP'); ?> 110 computer_language: <?php echo COMPUTER_LANGUAGE; ?><br /> 111 <br /><br /> 112 113 在模板中包括文件<br /> 114 <hr><br> 115 this is footer template 116 117 118 <hr><br> 119 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