《Php笔记3.5》ThinkPHP 模板(下)——标签,布局
模板作为 MVC 中 View 的高级应用,提供了丰富的视图渲染功能,对于项目实战来说,掌握上部分讲解的变量输出、函数和模板替换规则的知识是远远不够的,我们可以利用 ThinkPHP 内置的标签,甚至自定义标签库来简化模板,通过模板布局和继承机制,打造目录结构直观、便于维护的视图层,模板知识是开发中大型应用的基础,在后续的实战课程中会大量使用本课程的知识
ThinkPHP 模板:模板标签
本课时讲解 ThinkPHP 模板内置标签的用法,以及如何关闭局部模板标签的解析,达到原样输出的目的。
volist标签,empty标签,compare标签,lt等比较标签,if/else标签,模板替换
数据获取,function.php:
1 /* 2 * 获取球星测试数据 3 * @return array 4 */ 5 function get_user_friends(){ 6 $friends = array( 7 array( 8 'username' => '科比', 9 'avatar' => '1.jpg', 10 'age' => 37, 11 'tags' => array('81分','总冠军','美如画') 12 ), 13 array( 14 'username' => '詹姆斯', 15 'avatar' => '2.jpg', 16 'age' => 30, 17 'tags' => array('控场','暴力','全面') 18 ), 19 array( 20 'username' => '库里', 21 'avatar' => '3.jpg', 22 'age' => 26, 23 'tags' => array('3分','运球','总冠军') 24 ), 25 array( 26 'username' => '莫里斯', 27 'avatar' => null, 28 'age' => 17, 29 'tags' => array('球员','后卫','NBA') 30 ), 31 ); 32 33 return $friends; 34 }
控制器 indexController.class.php:
$this->assign('friends', get_user_friends());
给头像图片设置一个目录在/Public/avatar,设置配置项config:
'TMPL_PARSE_STRING' => array( '__AVATAR__'=>'/Uploads/avatar' )
index.html 模板文件:
1 <!-- 球星列表 --> 2 <div class="panel panel-default"> 3 <div class="panel-heading"> 4 <h3 class="panel-title">球星列表</h3> 5 </div> 6 <ul class="list-group media-list"> 7 <!-- volist循环 --> 8 <volist name="friends" id="friend" empty="没有球星数据"> 9 <li class="list-group-item media"> 10 <a class="pull-left" href="#"> 11 <empty name="friend['avatar']"> 12 <img src="__AVATAR__/default.jpg" width="100"> 13 <else/> 14 <img src="__AVATAR__/{$friend['avatar']}" width="100"></empty> 15 </a> 16 <div class="media-body"> 17 <h4 class="media-heading"> 18 {$friend['username']}:{$friend['age']}岁 19 <!-- 20 eq : == 21 neq : != 22 gt : > 23 egt : >= 24 lt : < 26 elt : <= 27 heq : === 28 nheq : !== 29 --> 30 31 <!-- eq,判断年龄是否是30岁 --> 32 <compare name="friend['age']" value="30" type="eq"> 33 <span class="label label-warning">您正好30岁,真是猿粪啊!</span> 34 </compare> 35 36 <!-- if else --> 37 <!-- 如果年龄小于18岁 --> 38 <if condition="$friend['age'] lt 18"> 39 <span class="pull-right">因为未成年,所以不显示</span> 40 <else/> 41 <a href="#" class="pull-right btn btn-warning">这项操作需要满18岁</a> 42 </if> 43 </h4> 44 45 <p> 46 <!-- 比较标签 --> 47 48 <!-- lt方式比较年龄 --> 49 <lt name="friend['age']" value="18">未成年</lt> 50 <!-- compare方式比较 --> 51 <compare name="friend['age']" value="18" type="lt"> 52 <span class="text-danger">注意,compare标签也表示:{$friend['username']}未成年!</span> 53 </compare> 54 <!-- egt方式比较年龄 --> 55 <egt name="friend['age']" value="35">中年人</egt> 56 <!-- between方式判断年龄区间 --> 57 <between name="friend['age']" value="18,34">青年</between> 58 </p> 59 60 <div> 61 标签: 62 <!-- Volist循环嵌套输出tags标签 --> 63 <volist name="friend['tags']" id='tag'> 64 <span class="label label-success">{$tag}</span> 65 66 </volist> 67 </div> 68 </div> 69 </li> 70 </volist> 71 </ul> 72 </div>
访问页面:
for标签,原生PHP标签,literal原样输出
1 <!-- For循环 --> 2 <div class="panel panel-default"> 3 <div class="panel-heading"> 4 <h3 class="panel-title">For标签循环输出</h3> 5 </div> 6 <div class="list-group"> 7 <for start="0" end="5" step="1"> 8 <a href="#" class="list-group-item">使用for标签循环了{$i+1}次</a> 9 </for> 10 </div> 11 </div> 12 13 <!-- PHP循环 --> 14 <div class="panel panel-default"> 15 <div class="panel-heading"> 16 <h3 class="panel-title">使用PHP标签实现php代码循环输出</h3> 17 </div> 18 <div class="list-group"> 19 <php> 20 for($i=0; $i<5; $i++){ 21 echo '<a href="#" class="list-group-item">使用PHP标签循环了'.($i+1).'次</a>'; 22 } 23 </php> 24 </div> 25 </div> 26 27 <!-- literal原样输出 --> 28 <div class="panel panel-default"> 29 <div class="panel-heading"> 30 <h3 class="panel-title">原样输出</h3> 31 </div> 32 <div class="panel-body"> 33 <blockquote> 34 <pre> 35 <literal>我们可以使用{$user.user}的方式来输出用户名</literal> 36 </pre> 37 </blockquote> 38 </div> 39 </div>
ThinkPHP模板:标签库
本课时讲解 ThinkPHP 自带的模板标签库以及标签库的加载方式,配置框架的内置标签库以及自定义标签库。
内置标签库解析文件位置:/ThinkPHP/Library/Think/Template/Cx.class.php
新增一个自定义标签库:
创建Application/Views/TagLib目录,新建Jike.class.php文件: (标签库类文件)
1 <?php 2 namespace Views\TagLib; 3 use Think\Template\TagLib; 4 5 /** 6 * 7 */ 8 class Jike extends TagLib 9 { 10 11 /** 12 * 定义标签列表 13 */ 14 protected $tags = array( 15 'friends' => array( 16 'attr' => 'uid', 17 'close' => 1 18 ) 19 ); 20 21 public function _friends($tag,$content) 22 { 23 $id=$tag['uid']; 24 $name=$tag['name']; 25 $empty=$tag['empty']; 26 $unique=rand(); 27 28 $parse_string='<?php '; 29 $parse_string.='$_FRIENDS_'.$unique.'=get_user_friends('.$id.');'; 30 $parse_string.='if(empty($_FRIENDS_'.$unique.')){echo $empty;}'; 31 $parse_string.='else'; 32 $parse_string.='{'; 33 $parse_string.='foreach ($_FRIENDS_' . $unique . ' as $key => $' . $name . ') {'; 34 $parse_string.=' ?>'; 35 $parse_string.=$content; 36 $parse_string.='<?php '; 37 $parse_string.='}'; 38 $parse_string.='}'; 39 $parse_string.=' ?>'; 40 41 return $parse_string; 42 } 43 } 44 ?>
补上里面的get_user_friends()方法(获取数据),function.php
1 <?php 2 3 /* 4 * 获取球星测试数据 5 * @return array 6 */ 7 function get_user_friends($id=''){ 8 $friends = array( 9 array( 10 'username' => '科比'.$id, 11 'avatar' => '1.jpg', 12 'age' => 37, 13 'tags' => array('81分','总冠军','美如画') 14 ), 15 array( 16 'username' => '詹姆斯'.$id, 17 'avatar' => '2.jpg', 18 'age' => 30, 19 'tags' => array('控场','暴力','全面') 20 ), 21 array( 22 'username' => '库里'.$id, 23 'avatar' => '3.jpg', 24 'age' => 26, 25 'tags' => array('3分','运球','总冠军') 26 ), 27 array( 28 'username' => '莫里斯'.$id, 29 'avatar' => null, 30 'age' => 17, 31 'tags' => array('球员','后卫','NBA') 32 ), 33 ); 34 35 return $friends; 36 }
加载标签库或预加载标签设置(TAGLIB_PRE_LOAD)
加载标签库,模板文件中:
<taglib name="Views\TagLib\Jike"/>
或预加载标签设置,config中:
'TAGLIB_PRE_LOAD'=>'Views\TagLib\Jike', //'TAGLIB_BUILD_IN'=>'Views\TagLib\Jike', //配置内置标签库,标签就不用加前缀Jike:...
模板文件中使用标签:
<div class="list-group"> <Jike:friends name="jike_user" uid="2" empty="没有数据"> <a href="#" class="list-group-item">{$jike_user['username']}</a> </Jike:friends> </div>
访问页面,输出结果:
标签在程序中是怎样一个实现原理呢?
我们查看缓存文件后,看到标签段代码已经被解析成了:
<div class="list-group"> <?php $_FRIENDS_16864=get_user_friends(2);if(empty($_FRIENDS_16864)){echo $empty;}else{foreach ($_FRIENDS_16864 as $key => $jike_user) { ?><a href="#" class="list-group-item"><?php echo ($jike_user['username']); ?></a><?php }} ?> </div>
我们看到,标签内容全部被解析成了php语句。
所以实现原理是:
1.标签解析,标签段代码通过自定义标签库中的标签解析类,解析成
<?php $_FRIENDS_16864=get_user_friends(2);if(empty($_FRIENDS_16864)){echo $empty;}else{foreach ($_FRIENDS_16864 as $key => $jike_user) { ?><a href="#" class="list-group-item">{$jike_user['username']}</a><?php }} ?>
2.数据的获取和循环
都是在标签解析文件中实现,并且将参数的名称定义成标签里的tag['name'],这样就实现了标签输出内容名称jike_user自定义的功能。
3.界定符内代码解析成PHP
{$jike_user['username']}
最后通过Thinkphp的界定符解析,将标签内容解析成php代码
所以最终的原理就是把所有的标签解析成php语句,再通过php服务器,输出成html。
ThinkPHP模板:模板布局和继承
本课时讲解 ThinkPHP 模板的布局和继承,模板继承在实际项目中应用非常广泛,可以极大地提高开发效率,优化模板的结构。
暂时不是特别重要,也不难,暂略。马上开始学习模型数据库课程。