Thinkphp 模板/内置标签

发布时间 2023-06-16 11:07:35作者: 声声慢43

 来自:https://blog.csdn.net/qq_42176520/category_7824704.html

模板替换

在进行模板渲染之前,系统还会对读取的模板内容进行一些特殊字符串替换操作,也就是实现了模板输出的替换和过滤。该替换操作仅针对内置的模版引擎。

这个机制可以使得模板文件的定义更加方便,默认的替换规则有:

: 会替换成当前网站的地址(不含域名)
/index.php?s=: 会替换成当前应用的URL地址 (不含域名)
__MODULE__:会替换成当前模块的URL地址 (不含域名)
__CONTROLLER__(__或者/index.php?s=-news 兼容考虑): 会替换成当前控制器的URL地址(不含域名)
/index.php?s=-news-read:会替换成当前操作的URL地址 (不含域名)
/n/s2e2/: 会替换成当前的页面URL
/Public:会被替换成当前网站的公共目录 通常是 /Public

默认情况下,模板替换只会替换模板文件的特殊字符串,不会替换动态数据中的输出的内容。

注意这些特殊的字符串是严格区别大小写的,并且这些特殊字符串的替换规则是可以更改或者增加的,我们只需要在应用或者模块的配置文件中配置TMPL_PARSE_STRING就可以完成。如果有相同的数组索引,就会更改系统的默认规则。例如:

'TMPL_PARSE_STRING' =>array(
    '/Public' => '/Common', // 更改默认的/Public 替换规则
    '__JS__' => '/Public/JS/', // 增加新的JS类库路径替换规则
    '__UPLOAD__' => '/Uploads', // 增加新的上传路径替换规则
)

 

有了模板替换规则后,模板中的所有/Public字符串都会被替换,那如果确实需要输出/Public字符串到模板呢,我们可以通过增加替换规则的方式,例如:

'TMPL_PARSE_STRING' =>array(
    '--PUBLIC--' => '/Public', // 采用新规则输出`/Public`字符串
)

 

这样增加替换规则后,如果我们要在模板中使用/Public字符串,只需要在模板中添加--PUBLIC--,其他替换字符串的输出方式类似。

修改定界符

模板文件可以包含普通模板标签和XML模板标签,标签的定界符都可以重新配置。

普通标签

内置模板引擎的普通模板标签默认以{ 和 } 作为开始和结束标识,并且在开始标记紧跟标签的定义,如果之间有空格或者换行则被视为非模板标签直接输出。 例如:{$name} 、{$vo.name} 、{$vo['name']|strtoupper} 都属于普通模板标签。

要更改普遍模板的起始标签和结束标签,请使用下面的配置参数:

TMPL_L_DELIM //模板引擎普通标签开始标记
TMPL_R_DELIM //模板引擎普通标签结束标记

例如在项目配置文件中增加下面的配置:

'TMPL_L_DELIM' => '<{',
'TMPL_R_DELIM' => '}>'

普通标签的定界符就被修改了,原来的 {$name} 和 {$vo.name} 必须使用 <{$name}> 和 <{$vo.name}> 才能生效了。

如果你定制了普通标签的定界符,记得修改下默认的系统模板。

XML标签

普通模板标签主要用于模板变量输出和模板注释。如果要使用其它功能,请使用XML模板标签。XML模板标签可以用于模板变量输出、文件包含、条件控制、循环输出等功能,而且完全可以自己扩展功能。如果你觉得XML标签无法在正在使用的编辑器里面无法编辑,还可以更改XML标签库的起始和结束标签,请修改下面的配置参数:

TAGLIB_BEGIN //标签库标签开始标签
TAGLIB_END //标签库标签结束标记

 例如在项目配置文件中增加下面的配置:

'TAGLIB_BEGIN'=>'[',
'TAGLIB_END'=>']',

原来的

<eq name="name" value="value">
    相等
<else/>
    不相等
</eq>

就必须改成

[eq name="name" value="value"]
    相等
[else/]
    不相等
[/eq]

注意:XML标签和普通标签的定界符不能冲突,否则会导致解析错误。

变量输出

在模板中输出变量的方法很简单,例如,在控制器中我们给模板变量赋值:

$name = 'ThinkPHP';
$this->assign('name',$name);
$this->display();
//然后就可以在模板中使用:
Hello,{$name}!
//模板编译后的结果就是:
Hello,<?php echo($name);?>//运行结果
Hello,ThinkPHP!

注意模板标签的{$之间不能有任何的空格,否则标签无效。所以,Hello,{ $name}!将不会正常输出name变量,而是直接保持不变输出: Hello,{ $name}!

普通标签默认开始标记是{,结束标记是 }。也可以通过设置TMPL_L_DELIMTMPL_R_DELIM进行更改。

模板标签的变量输出根据变量类型有所区别,刚才我们输出的是字符串变量,如果是数组变量:

$data['name'] = 'ThinkPHP';
$data['email'] = 'thinkphp@qq.com';
$this->assign('data',$data);
//在模板中我们可以用下面的方式输出:
Name:{$data.name}
Email:{$data.email}

或者用下面的方式也是有效:
Name:{$data['name']}
Email:{$data['email']}
//当我们要输出多维数组的时候,往往要采用后面一种方式。

如果data变量是一个对象(并且包含有name和email两个属性),那么可以用下面的方式输出:

Name:{$data:name}
Email:{$data:email}

//或者
Name:{$data->name}
Email:{$data->email}

三元运算

模板可以支持三元运算符,例如:

{$status?'正常':'错误'}
{$info['status']?$info['msg']:$info['error']}

注意:三元运算符中暂时不支持点语法。

运算符

运算符使用示例
+ {$a+$b}
- {$a-$b}
* {$a*$b}
/ {$a/$b}
% {$a%$b}
++ {$a++} 或 {++$a}
-- {$a--} 或 {--$a}
综合运算 {$a+$b*10+$c}

 

在使用运算符的时候,不再支持点语法和常规的函数用法,例如:

{$user.score+10} //错误的
{$user['score']+10} //正确的
{$user['score']*$user['level']} //正确的
{$user['score']|myFun*10} //错误的
{$user['score']+myFun($user['level'])} //正确的

默认值输出

我们可以给变量输出提供默认值,例如:

{$user.nickname|default="这家伙很懒,什么也没留下"}

对系统变量依然可以支持默认值输出,例如:

{$Think.get.name|default="名称为空"}

默认值和函数可以同时使用,例如:

{$Think.get.name|getName|default="名称为空"}
{$Think.get.name|getName|default="名称为空"}应该改成{$Think.get.name|default="名称为空"|getName}

使用函数

对模板输出变量使用函数,可以使用:

{$data.name|md5} 
<!-- 编译后的结果是:-->
<?php echo (md5($data['name'])); ?>

如果函数有多个参数需要调用,则使用:

{$create_time|date="y-m-d",###}
<!-- 编译后的结果是:-->
<?php echo (date("y-m-d",$create_time)); ?>

{$create_time|date="y-m-d",###}表示date函数传入两个参数,每个参数用逗号分割,这里第一个参数是y-m-d,第二个参数是前面要输出的create_time变量,因为该变量是第二个参数,因此需要用###标识变量位置。

如果前面输出的变量在后面定义的函数的第一个参数,则可以直接使用:

{$data.name|substr=0,3}
<!--表示输出 -->
<?php echo (substr($data['name'],0,3)); ?>
<!--虽然也可以使用: -->
{$data.name|substr=###,0,3}
<!--但完全没用这个必要。 -->

还可以支持多个函数过滤,多个函数之间用“|”分割即可,例如:

{$name|md5|strtoupper|substr=0,3}
<!--编译后的结果是: -->
<?php echo (substr(strtoupper(md5($name)),0,3)); ?>

函数会按照从左到右的顺序依次调用。

如果你觉得这样写起来比较麻烦,也可以直接这样写:

{:substr(strtoupper(md5($name)),0,3)}

变量输出使用的函数可以支持内置的PHP函数或者用户自定义函数,甚至是静态方法。

 

模板继承

https://blog.csdn.net/qq_42176520/article/details/81152937

标签库

https://blog.csdn.net/qq_42176520/article/details/81152863

系统变量

 https://blog.csdn.net/qq_42176520/article/details/81152770

模板布局

 https://blog.csdn.net/qq_42176520/article/details/81153229

 原样输出

 https://blog.csdn.net/qq_42176520/article/details/81153215
   
   

IF标签

用法示例:

<if condition="($name eq 1) OR ($name gt 100) "> value1
<elseif condition="$name eq 2"/>value2
<else /> value3
</if>

在condition属性中可以支持eq等判断表达式,同上面的比较标签,但是不支持带有”>”、”<”等符号的用法,因为会混淆模板解析,所以下面的用法是错误的:

<if condition="$id < 5 ">value1
<else /> value2
</if>

 可以试一下修改模板标签为{},是否这样就可以支持”>”、”<”等符号

除此之外,我们可以在condition属性里面使用php代码,例如:

<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>

或者知道user变量是对象

<if condition="$user:name neq 'ThinkPHP'">ThinkPHP
<else /> other Framework
</if>

由于if标签的condition属性里面基本上使用的是php语法,尽可能使用判断标签和Switch标签会更加简洁,原则上来说,能够用switch和比较标签解决的尽量不用if标签完成。因为switch和比较标签可以使用变量调节器和系统变量。如果某些特殊的要求下面,IF标签仍然无法满足要求的话,可以使用原生php代码或者PHP标签来直接书写代码。

Volist标签

volist标签通常用于查询数据集(select方法)的结果输出,通常模型的select方法返回的结果是一个二维数组,可以直接使用volist标签进行输出。 在控制器中首先对模版赋值:

$User = M('User');
$list = $User->limit(10)->select();
$this->assign('list',$list);

在模版定义如下,循环输出用户的编号和姓名:

<volist name="list" id="vo">
    {$vo.id}:{$vo.name}<br/>
</volist>

Volist标签的name属性表示模板赋值的变量名称,因此不可随意在模板文件中改变。id表示当前的循环变量,可以随意指定,但确保不要和name属性冲突,例如:

<volist name="list" id="data">
    {$data.id}:{$data.name}<br/>
</volist>

支持输出查询结果中的部分数据,例如输出其中的第5~15条记录

<volist name="list" id="vo" offset="5" length='10'>
    {$vo.name}
</volist>

输出偶数记录

<volist name="list" id="vo" mod="2" >
    <eq name="mod" value="1">{$vo.name}</eq>
</volist>

Mod属性还用于控制一定记录的换行,例如:

<volist name="list" id="vo" mod="5" >
    {$vo.name}
    <eq name="mod" value="4"><br/></eq>
</volist>

为空的时候输出提示:

<volist name="list" id="vo" empty="暂时没有数据" >
    {$vo.id}|{$vo.name}
</volist>

empty属性不支持直接传入html语法,但可以支持变量输出,例如:

$this->assign('empty','<span class="empty">没有数据</span>');
$this->assign('list',$list);

然后在模板中使用:

<volist name="list" id="vo" empty="$empty" >
    {$vo.id}|{$vo.name}
</volist>

输出循环变量

<volist name="list" id="vo" key="k" >
    {$k}.{$vo.name}
</volist>

如果没有指定key属性的话,默认使用循环变量i,例如:

<volist name="list" id="vo" >
    {$i}.{$vo.name}
</volist>

如果要输出数组的索引,可以直接使用key变量,和循环变量不同的是,这个key是由数据本身决定,而不是循环控制的,例如:

<volist name="list" id="vo" >
    {$key}.{$vo.name}
</volist>

模板中可以直接使用函数设定数据集,而不需要在控制器中给模板变量赋值传入数据集变量,如:

<volist name=":fun('arg')" id="vo">
    {$vo.name}
</volist>

Foreach标签

foreach标签类似与volist标签,只是更加简单,没有太多额外的属性,例如:

<foreach name="list" item="vo">
  {$vo.id}:{$vo.name}
</foreach>

name表示数据源,item表示循环变量。

可以输出索引 {$key},如下:

<foreach name="list" item="vo" >
    {$key}|{$vo}
</foreach>

也可以定义索引的变量名

<foreach name="list" item="vo" key="k" >
    {$k}|{$vo}
</foreach>

For标签

用法:

<for start="开始值" end="结束值" comparison="" step="步进值" name="循环变量名" >
</for>

开始值、结束值、步进值和循环变量都可以支持变量,开始值和结束值是必须,其他是可选。comparison 的默认值是lt;name的默认值是i,步进值的默认值是1,举例如下:

<for start="1" end="100">
    {$i}
</for>

解析后的代码是

for ($i=1;$i<100;$i+=1){
    echo $i;
}

包含文件

在当前模版文件中包含其他的模版文件使用include标签,标签用法:

<include file='模版表达式或者模版文件1,模版表达式或者模版文件2,...' />

使用模版表达式

模版表达式的定义规则为:模块@主题/控制器/操作

例如:

可能为:

<include file="Public/header" /> // 包含头部模版header
<include file="Public/menu" /> // 包含菜单模版menu
<include file="Blue/Public/menu" /> // 包含blue主题下面的menu模版
 可以一次包含多个模版,例如:
<include file="Public/header,Public/menu" />

注意,包含模版文件并不会自动调用控制器的方法,也就是说包含的其他模版文件中的变量赋值需要在当前操作中完成。

使用模版文件

可以直接包含一个模版文件名(包含完整路径),例如:

<include file="./Application/Home/View/default/Public/header.html" />

传入参数

无论你使用什么方式包含外部模板,Include标签支持在包含文件的同时传入参数,例如,下面的例子我们在包含header模板的时候传入了title和keywords变量:

<include file="Public/header" title="ThinkPHP框架" keywords="开源WEB开发框架" />

就可以在包含的header.html文件里面使用title和keywords变量,如下:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>[title]</title>
    <meta name="keywords" content="[keywords]" />
</head>

注意:由于模板解析的特点,从入口模板开始解析,如果外部模板有所更改,模板引擎并不会重新编译模板,除非在调试模式下或者缓存已经过期。如果部署模式下修改了包含的外部模板文件后,需要把模块的缓存目录清空,否则无法生效。

Switch标签

用法:

<switch name="变量" >
    <case value="值1" break="0或1">输出内容1</case>
    <case value="值2">输出内容2</case>
    <default />默认情况
</switch>

使用方法如下:

<switch name="User.level">
    <case value="1">value1</case>
    <case value="2">value2</case>
    <default />default
</switch>

其中name属性可以使用函数以及系统变量,例如:

<switch name="Think.get.userId|abs">
    <case value="1">admin</case>
    <default />default
</switch>

对于case的value属性可以支持多个条件的判断,使用”|”进行分割,例如:

<switch name="Think.get.type">
    <case value="gif|png|jpg">图像格式</case>
    <default />其他格式
</switch>

表示如果$_GET["type"] 是gif、png或者jpg的话,就判断为图像格式。

Case标签还有一个break属性,表示是否需要break,默认是会自动添加break,如果不要break,可以使用:

<switch name="Think.get.userId|abs">
    <case value="1" break="0">admin</case>
    <case value="2">admin</case>
    <default />default
</switch>

也可以对case的value属性使用变量,例如:

<switch name="User.userId">
    <case value="$adminId">admin</case>
    <case value="$memberId">member</case>
    <default />default
</switch>

使用变量方式的情况下,不再支持多个条件的同时判断。

范围判断标签 IN和NOTIN

范围判断标签包括in notin between notbetween四个标签,都用于判断变量是否中某个范围。

IN和NOTIN

用法: 假设我们在后台控制器中给id赋值为1,在前端可以使用in标签来判断模板变量是否在某个范围内

<!--后台-->
$id = 1;
$this->assign('id',$id);
<!--前端-->
<in name="id" value="1,2,3">id在范围内</in>
<!--输出:id在范围内-->

如果判断不在某个范围内,可以使用: id不在范围内 可以把上面两个标签合并成为:

<in name="id" value="1,2,3">
    id在范围内
<else/>
    id不在范围内
</in>

name属性还可以支持直接判断系统变量,例如:

<in name="Think.get.id" value="1,2,3">
    $_GET['id'] 在范围内
</in>

更多的系统变量用法可以参考系统变量部分。

value属性也可以使用变量,例如:

<in name="id" value="$range">id在范围内</in>

$range变量可以是数组,也可以是以逗号分隔的字符串。

value属性还可以使用系统变量,例如:

<in name="id" value="$Think.post.ids">id在范围内</in>

BETWEEN 和 NOTBETWEEN

可以使用between标签来判断变量是否在某个区间范围内,使用notbetween标签来判断变量不在某个范围内,也可以使用else标签把两个用法合并,例如:

<!--1-->
<between name="id" value="1,10">输出内容1</between>
<!--2-->
<notbetween name="id" value="1,10">输出内容2</notbetween>
<!--3-->
<between name="id" value="1,10">
    输出内容1
<else/>
    输出内容2
</between>

当使用between标签的时候,value只需要一个区间范围,也就是只支持两个值,后面的值无效,例如

<!-- 实际判断的范围区间是1~3,而不是1~10 --> 
<between name="id" value="1,3,10">
输出内容1
</between>

,也可以支持字符串判断,例如:

<between name="id" value="A,Z"> 输出内容1</between>

name属性可以直接使用系统变量,value属性也可以使用变量,变量的值可以是字符串或者数组,还可以支持系统变量。例如:

<between name="Think.post.id" value="1,5">输出内容1</between>
<between name="id" value="$range">输出内容1</between>
<between name="id" value="$Think.get.range">输出内容1</between>

RANGE

也可以直接使用range标签,替换前面的判断用法:

<range name="id" value="1,2,3" type="in">输出内容1</range>

 

其中type属性的值可以用in/notin/between/notbetween,其它属性的用法和IN或者BETWEEN一致。