快速入门 7:视图
最后更新于:2022-04-01 00:18:29
# 快速入门(七):视图
在了解了控制器和模型操作后,我们开始熟悉视图部分,ThinkPHP中的视图主要就是指模板文件和模板引擎,本篇首先了解下模板定义以及如何进行模板赋值并渲染输出的。
## 模板定义
每个模块的模板文件是独立的,为了对模板文件更加有效的管理,ThinkPHP对模板文件进行目录划分,默认的模板文件定义规则是:
~~~
视图目录/[模板主题/]控制器名/操作名+模板后缀
~~~
默认的视图目录是模块的View目录(模块可以有多个视图文件目录,这取决于你的应用需要),框架的默认视图文件后缀是.html。
> 大多数情况下你不需要主题功能,因此新版模板主题默认是空(表示不启用模板主题功能)。
一般情况下,模板文件都在模块的视图目录下面,并且是以模块下面的控制器名为目录,然后是每个控制器的具体操作模板文件,例如:
User控制器的add操作对应的模板文件就应该是:`./Application/Home/View/User/add.html`
如果你的默认视图层不是View,例如:
~~~
// 设置默认的视图层名称
'DEFAULT_V_LAYER' => 'Template',
~~~
那么,对应的模板文件就变成了:`./Application/Home/Template/User/add.html`。
模板文件的默认后缀的情况是.html,也可以通过 **TMPL_TEMPLATE_SUFFIX** 来配置成其他的。例如,我们可以配置:
~~~
'TMPL_TEMPLATE_SUFFIX'=>'.tpl'
~~~
定义后,User控制器的add操作 对应的模板文件就变成是: `./Application/Home/View/User/add.tpl`
如果觉得目录结构太深,可以通过设置 **TMPL_FILE_DEPR** 参数来配置简化模板的目录层次,例如设置:
~~~
'TMPL_FILE_DEPR'=>'_'
~~~
默认的模板文件就变成了:`./Application/Home/View/User_add.html`
如果需要,允许把模板目录设置到模块目录之外,有两种方式:
**一、改变所有模块的模板文件目录**
可以通过设置TMPL_PATH常量来改变所有模块的模板目录所在,例如:
~~~
define('TMPL_PATH','./Template/');
~~~
原来的`./Application/Home/View/User/add.html`变成了`./Template/Home/User/add.html`。
> 注意TMPL_PATH常量最后使用“/”符号结尾。
**二、改变某个模块的模板文件目录**
我们可以在模块配置文件中设置**VIEW_PATH**参数单独定义某个模块的视图目录,例如:
~~~
'VIEW_PATH'=>'./Theme/'
~~~
把当前模块的视图目录指定到最外层的Theme目录下面,而不是放到当前模块的View目录下面。 原来的`./Application/Home/View/User/add.html`变成了`./Theme/User/add.html`。
> 注意:如果同时定义了TMPL_PATH常量和VIEW_PATH设置参数,那么以当前模块的VIEW_PATH参数设置优先。
## 模板渲染
渲染模板输出最常用的是使用display方法,调用格式:
~~~
display('[模板文件]'[,'字符编码'][,'输出类型'])
~~~
模板文件的写法支持下面几种:
|用法 |描述|
|--------|--------|
|不带任何参数 |自动定位当前操作的模板文件|
|[模块@][控制器:][操作] |常用写法,支持跨模块 模板主题可以和theme方法配合|
|完整的模板文件名 |直接使用完整的模板文件名(包括模板后缀)|
下面是一个最典型的用法,不带任何参数:
~~~
// 不带任何参数 自动定位当前操作的模板文件
$this->display();
~~~
表示系统会按照默认规则自动定位模板文件,其规则是:
* 如果当前没有启用模板主题则定位到:`当前模块/默认视图目录/当前控制器/当前操作.html` ;
* 如果有启用模板主题则定位到:`当前模块/默认视图目录/当前主题/当前控制器/当前操作.html`;
* 如果有更改TMPL_FILE_DEPR设置(假设 'TMPL_FILE_DEPR'=>'_')的话,则上面的自动定位规则变成: `当前模块/默认视图目录/当前控制器_当前操作.html` 和 `当前模块/默认视图目录/当前主题/当前控制器_当前操作.html`。
所以通常display方法无需带任何参数即可输出对应的模板,这是模板输出的最简单的用法。
通常默认的视图目录是View
如果没有按照模板定义规则来定义模板文件(或者需要调用其他控制器下面的某个模板),可以使用:
~~~
// 指定模板输出
// 表示调用当前控制器下面的edit模板
$this->display('edit');
~~~
或者指定控制器
~~~
// 表示调用Member控制器下面的read模板
$this->display('Member:read');
~~~
如果我们使用了模板主题功能,那么也可以支持跨主题调用,使用:
~~~
// 调用blue主题下面的User控制器的edit模板
$this->theme('blue')->display('User:edit');
~~~
渲染输出不需要写模板文件的路径和后缀,确切地说,这里面的控制器和操作并不一定需要有实际对应的控制器和操作,只是一个目录名称和文件名称而已,例如,你的项目里面可能根本没有Public控制器,更没有Public控制器的menu操作,但是一样可以使用
~~~
$this->display('Public:menu');
~~~
输出这个模板文件。
display方法支持在渲染输出的时候指定输出编码和类型,例如,可以指定编码和类型:
~~~
// 输出XML页面类型(配合你的应用需求可以输出很多类型)
$this->display('read', 'utf-8', 'text/xml');
~~~
事情总有特例,如果的模板目录是自定义的,或者根本不需要按模块进行分目录存放,那么默认的display渲染规则就不能处理,这个时候,我们就需要使用另外一种方式来应对,直接传入模板文件名即可,例如:
~~~
$this->display('./Template/Public/menu.html');
~~~
这种方式需要指定模板路径和后缀,这里的Template/Public目录是位于当前项目入口文件位置下面(当然如果需要也可以使用绝对路径)。
如果是其他的后缀文件,也支持直接输出,例如:
~~~
$this->display('./Template/Public/menu.tpl');
~~~
只要`./Template/Public/menu.tpl`是一个实际存在的模板文件。
> 要注意模板文件位置是相对于项目的入口文件,而不是模板目录。
如果需要获取渲染模板的输出内容而不是直接输出,可以使用fetch方法。
fetch方法的用法除了不需要指定输出编码和类型外其它和display基本一致,格式:
~~~
fetch('模板文件')
~~~
模板文件的调用方法和display方法完全一样,区别就在于fetch方法渲染后不是直接输出,而是返回渲染后的内容,例如:
~~~
$content = $this->fetch('Member:edit');
~~~
使用fetch方法获取渲染内容后,你可以进行过滤和替换等操作,或者用于对输出的复杂需求。
## 渲染内容
如果你没有定义任何模板文件,或者把模板内容存储到数据库中的话,你就需要使用show方法来渲染输出了,show方法的调用格式:
~~~
show('渲染内容'[,'字符编码'][,'输出类型'])
~~~
例如,
~~~
$this->show($content);
// 也可以指定编码和类型
$this->show($content, 'utf-8', 'text/xml');
~~~
> 注意:show方法中的内容也可以支持模板解析。
## 模板赋值
如果要在模板中输出变量,必须在在控制器中把变量传递给模板,系统提供了assign方法对模板变量赋值,无论何种变量类型都统一使用assign赋值。
~~~
$this->assign('name',$value);
~~~
assign方法必须在display和show方法之前调用,并且系统只会输出设定的变量,其它变量不会输出(系统变量例外),一定程度上保证了变量的安全性。
> 系统变量可以通过特殊的标签输出,无需赋值模板变量
赋值后,就可以在模板文件中输出变量了,如果使用的是内置模板的话,就可以这样输出:
~~~
{$name}
~~~
如果要同时输出多个模板变量,可以使用下面的方式:
~~~
$array['name'] = 'thinkphp';
$array['email'] = 'liu21st@gmail.com';
$array['phone'] = '12335678';
$this->assign($array);
~~~
这样,就可以在模板文件中同时输出name、email和phone三个变量。
模板变量的输出根据不同的模板引擎有不同的方法,我们在后面会专门讲解内置模板引擎的用法。如果你使用的是PHP本身作为模板引擎的话 ,就可以直接在模板文件里面输出了:
~~~
<?php echo $name.'['.$email.''.$phone.']';?>
~~~
如果采用内置的模板引擎,可以使用:
~~~
{$name} [ {$email} {$phone} ]
~~~
输出同样的内容。
## 总结
通过本篇的学习,我们大概掌握了如何定义模板文件和进行模板渲染输出,以及如何赋值模板变量,后面我们将会学习如何在模板文件中使用标签来简化你的书写。