18.7 模板
模板定义了一组数据的显示方式,控制器可以给模板赋值,模板将其显示到视图界面。通过一些特定的模板标签可以灵活控制视图中的数据展现。
18.7.1 模板赋值与变量输出
前面只是在控制器方法里面直接输出,而没有使用视图模板功能,现在就来了解一下如何把变量赋值到模板并渲染输出。
ThinkPHP使用assign方法对模板数据进行赋值。例如,修改User控制器的index方法:
application/index/controller/user.php文件内容
<?php
namespace app\index\controller;
use app\index\model\User as UserModel;
class User extends\think\Controller
{
//获取用户数据并输出
public function index(){
$list=UserModel::all();
//echo "<pre>";
//var_dump($list);
//list:数组,存储的是用户对象
$this->assign('list',$list);
//count:数组的数量
$this->assign('count',count($list));
var_dump(count($list));
return $this->fetch('index');
}
}
与视图类有关的有4个方法:
● assign模板变量赋值。
● fetch渲染模板文件。
● display渲染内容。
● engine初始化模板引擎。
其中,assign和fetch是最常用的两个方法。
assign方法可以把任何类型的变量赋值给模板,关键在于如何输出——不同的变量类型需要采用不同的标签输出。fetch方法默认渲染输出的模板文件应该是当前控制器和操作对应的模板,在本例中也就是:
application/index/view/user/index.html
index.html内容
<html>
<head>
</head>
<body>
<!--使用volist标签输出从控制器传来来的数据"list"-->
{volist name='list' id='user'}
{$user.id}:{$user.nickname}:{$user.email}:{$user.create_time}<br/>
{/volist}
<br/>
总共有{$count}条数据:
</body>
</html>
浏览器访问http://tp5.jingpan.io/index/user,输出
绑定数据到模板输出有3种方式。
(1)使用assign方法,例如:
application/index/controller/user.php文件内容
<?php
namespace app\index\controller;
use app\index\model\User as UserModel;
class User extends\think\Controller
{
public function index(){
//模版变量赋值
$this->assign('name','ThinkPHP');
$this->assign('email','thinkphp@qq.com');
//或者批量赋值
$this->assign([
'name'=>'ThinkPHP',
'email'=>'thinkphp@qq.com'
]);
//渲染index模板
return $this->fetch('index');
}
}
application/index/view/user/index.html
<html>
<head>
</head>
<body>
名称:{$name}<br/>
邮件:{$email}
</body>
</html>
浏览器访问http://tp5.jingpan.io/index/user,输出
2)也可以使用传入参数的方法。fetch和display都可以传入模板变量,例如:
<?php
namespace app\index\controller;
use app\index\model\User as UserModel;
class User extends\think\Controller
{
public function index(){
return $this->fetch('index',[
'name'=>'ThinkPHP',
'email'=>'thinkphp@qq.com'
]);
}
}
或
<?php
namespace app\index\controller;
use app\index\model\User as UserModel;
class User extends\think\Controller
{
public function index(){
$content='{$name}-{$email}';
return $this->display($content,[
'name'=>'ThinkPHP',
'email'=>'thinkphp@qq.com'
]);
}
}
浏览器访问http://tp5.jingpan.io/index/user,输出
(3)还可以使用对象赋值绑定到模板输出,例如:
<?php
namespace app\index\controller;
use app\index\model\User as UserModel;
class User extends\think\Controller
{
public function index(){
$view=$this->view;
$view->name='ThinkPHP';
$view->email='thinkphp@qq.com';
//模板输出
return $view->fetch('index');
}
}
浏览器访问http://tp5.jingpan.io/index/user,输出
在模板中输出变量的方法很简单。例如,在控制器中给模板变量赋值:
不继承\think\Controller话,需要手动
实例化视图类
<?php
namespace app\index\controller;
use app\index\model\User as UserModel;
use think\View; //
class User
{
public function index(){
$view = new View;
$view ->name='thinkphp';
$view ->email='thinkphp@qq.com';
//fetch不指定默认为index模版文件
return $view->fetch('index');
}
}
模版文件调用
名称:{$name}<br/> 邮件:{$email}
模板标签的变量输出根据变量类型有所区别。刚才我们输出的是字符串变量,如果是数组变量:
<?php
namespace app\index\controller;
use app\index\model\User as UserModel;
use think\View; //
class User
{
public function index(){
$view = new View;
$data['name']='ThinkPHP';
$data['email']='thinkphp@qq.com';
$view->assign('data',$data);
//fetch不指定默认为index模版文件
return $view->fetch('index');
}
}
那么在模板中我们可以用下面的方式输出:
名称:{$data['name']}<br/> 邮件:{$data['email']}
或者用下面的方式也是有效的:
名称:{$data.name}<br/> 邮件:{$data.email}
如果data变量是一个对象(并且包含有name和email两个属性),那么可以用下面的方式输出:
<?php
namespace app\index\controller;
use think\View;
use app\index\model\Car;
class User
{
public function index(){
$view = new View;
$car1 =new Car();
$car1->setcolor('白色');
$car1->setweight('2.5');
$car1->setspeeed(10);
$view->assign('data',$car1);
//fetch不指定默认为index模版文件
return $view->fetch('index');
}
}
汽车名称:{$data:color}<br/> 汽车重量:{$data:weight}<br/> 汽车速度:{$data:speed}
18.7.2 使用函数和运算符
我们往往需要对模板输出变量使用函数,可以使用{$data.name|md5},编译后的结果是:
<?php echo md5($data); ?>
如果函数有多个参数需要调用,则使用:
{$data.create_time|date="y-m-d",###}
表示date函数传入两个参数,每个参数用逗号分割,这里第一个参数是y-m-d,第二个参数是前面要输出的create_time变量,因为该变量是第二个参数,因此需要用###标识变量位置,编译后的结果是:
<?php echo date("y-m-d",$data['create_time']); ?>
如果前面输出的变量在后面定义的函数的第一个参数,则可以直接使用:
{$data.name|substr=0,3}
表示输出:
<?php echo substr($data['name'],0,3); ?>
虽然也可以使用:
{$data.name|substr=###,0,3}
但是完全没有这个必要。
还可以支持多个函数过滤,多个函数之间用“|”分割即可,例如:
{$data.name|md5|strtoupper|substr=0,3}
编译后的结果是:
<?php echo substr(strtoupper(md5($data1['name'])),0,3); ?>
函数会按照从左到右的顺序依次调用。
如果觉得这样写起来比较麻烦,也可以直接写为:
{:substr(strtoupper(md5($data.name)),0,3)}
变量输出使用的函数可以支持内置的PHP函数或者用户自定义函数,甚至是静态方法。
也可以对模板输出使用运算符,包括对“+”“-”“*”“/”和“%”的支持,如表18-1所示。
18.7.3 模板标签
变量输出使用普通标签就足够了,但是要完成其他的控制、循环和判断功能,还需要借助模板引擎的标签库功能。系统内置标签库的所有标签无须引入标签库即可直接使用。本小节介绍一些常用标签。
1. volist标签
volist标签通常用于查询数据集(select方法)的结果输出。通常模型的select方法返回的结果是一个二维数组,可以直接使用volist标签进行输出。在控制器中首先对模板赋值:
$list=UserModel::all(); $this->assign('list',$list); return $this->fetch('index'); 循环输出用户的编号和姓名,在模板中定义如下:
{volist name='list' id='vo'} {$vo.id}:{$vo.nickname}<br/> {/volist}
volist标签的name属性表示模板赋值的变量名称,因此不可随意在模板文件中改变。id表示当前的循环变量,可以随意指定,但要确保不和name属性冲突,例如:
{volist name='list' id='data'} {$data.id}:{$data.nickname}<br/> {/volist}
输出偶数记录:
输出偶数记录:
{volist name='list' id='vo' mod='2'} {eq name='mod' value='1'}{$vo.id}{/eq}<br/> {/volist}
mod属性还用于控制一定记录的换行,例如:
{volist name='list' id='vo' mod='5'} {$vo.nickname} {eq name='mod' value='4'}<br/>{/eq} {/volist}
输出循环变量:
{volist name='list' id='vo' mod='5' key='k'} {$k}{$vo.nickname} {eq name='mod' value='4'}<br/>{/eq} {/volist}
如果没有指定key属性,默认使用循环变量i,例如:
{volist name='list' id='vo' mod='5'} {$i}{$vo.nickname} {eq name='mod' value='4'}<br/>{/eq} {/volist}
如果要输出数组的索引,可以直接使用key变量。和循环变量不同的是,这个key是由数据本身决定而不是循环控制的,例如:
{volist name='list' id='vo' mod='5'} {$key}{$vo.nickname} {eq name='mod' value='4'}<br/>{/eq} {/volist}
2. foreach标签
foreach标签类似于volist标签,只是更加简单,没有太多额外的属性,最简单的用法是:
{foreach $list as $vo} {$vo.id}:{$vo.nickname} {/foreach}
该用法解析后是最简洁的。也可以使用下面的用法:
{foreach name="list" item="vo"} {$vo.id}:{$vo.nickname} {/foreach}
{foreach name="list" id="vo"} {$vo.id}:{$vo.nickname} {/foreach}
name表示数据源,item表示循环变量(也可以换成id)。可以输出索引,例如:
{foreach name="list" item="vo"} {$key}--{$vo.id}:{$vo.nickname} {/foreach}
也可以定义索引的变量名:
{foreach name="list" item="vo" key='k'} {$k}--{$vo.id}:{$vo.nickname} {/foreach}
3. switch标签
switch标签用来进行条件判断,用法如下:
<!--switch标签 获取用户名,判断是否相等,相等,输出admin--> {switch $admin} {case value='admin' break="1"}admin{/case} {case value='123' break="1"}123{/case} {default/}default {/switch}
4. if标签
if标签在模板中非常常用,用法如下:
<!-- {if condition="($name==1) OR ($name>100)"}value1--> <!-- {elseif conditon="$name eq 2"/}value2--> <!-- {else/}value3-->
{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}
5. PHP标签
PHP代码可以和标签在模板文件中混合使用,可以在模板文件里面书写任意PHP语句代码,包括{php}echo 'Hello, world! '; {/php}和<? php echo 'Hello, world! ';? >两种方式。ThinkPHP官方建议使用PHP标签而非原生PHP代码。注意,PHP标签或者PHP代码里面就不能再使用标签(包括普通标签和XML标签)了。因此下面的几种方式都是无效的:
在php标签里面不能再使用PHP本身不支持的代码。
另外,模板引擎支持标签的多层嵌套功能,可以对标签库的标签指定嵌套。
在系统内置的标签中,volist、switch、if、elseif、else、foreach、compare(包括所有的比较标签)、(not)present、(not)empty、(not)defined等标签都可以嵌套使用,例如:
上面的标签可以用于输出双重循环。