Volist标签
Volist标签主要用于在模板中循环输出数据集或者多维数组。
通常模型的select和findall方法返回的结果是一个二维数组,可以直接使用volist标签进行输出。
在Action中首先对模版赋值:
$User = M('User');
$list = $User->select();
$this->assign('list',$list);
在模版定义如下,循环输出用户的编号和姓名:
<volist name="list" id="vo">
{$vo.id}
{$vo.name}
</volist>
Volist标签的name属性表示模板赋值的变量名称,因此不可随意在模板文件中改变。id表示当前的循环变量,可以随意指定,但确保不要和name属性冲突,例如:
<volist name="list" id="data">
{$data.id}
{$data.name}
</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" 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还有一个别名iterate,用法和volist是一样。
Foreach标签
foreach标签也是用于循环输出
<foreach name="list" item="vo" >
{$vo.id}
{$vo.name}
</foreach>
Foreach标签相对比volist标签简洁,没有volist标签那么多的功能。优势是可以对对象进行遍历输出,而volist标签通常是用于输出数组。
Switch标签
模板引擎支持Switch标签,格式为:
<switch name="变量" >
<case value="值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的value属性使用变量,例如:
<switch name="User.userId">
<case value="$adminId">admin</case>
<case value="$memberId">member</case>
<default />default
</switch>
使用变量方式的情况下,不再支持多个条件的同时判断。
比较标签
模板引擎提供了丰富的判断标签,比较标签的用法是:
<比较标签 name="变量" value="值">内容</比较标签>
系统支持的比较标签以及所表示的含义分别是:
eq或者 equal:等于
neq 或者notequal:不等于
gt:大于
egt:大于等于
lt:小于
elt:小于等于
heq:恒等于
nheq:不恒等于
他们的用法基本是一致的,区别在于判断的条件不同。
例如,要求name变量的值等于value就输出,可以使用:
<eq name="name" value="value">value</eq>
或者
<equal name="name" value="value">value</equal>
也可以支持和else标签混合使用:
<eq name="name" value="value">相等<else/>不相等</eq>
当 name变量的值大于5就输出
<gt name="name" value="5">value</gt>
当name变量的值不小于5就输出
<egt name="name" value="5">value</egt>
比较标签中的变量可以支持对象的属性或者数组,甚至可以是系统变量:
举例说明:
当vo对象的属性(或者数组,或者自动判断)等于5就输出
<eq name="vo.name" value="5">{$vo.name}</eq>
当vo对象的属性等于5就输出
<eq name="vo:name" value="5">{$vo.name}</eq>
当$vo['name']等于5就输出
<eq name="vo['name']" value="5">{$vo.name}</eq>
而且还可以支持对变量使用函数
当vo对象的属性值的字符串长度等于5就输出
<eq name="vo:name|strlen" value="5">{$vo.name}</eq>
变量名可以支持系统变量的方式,例如:
<eq name="Think.get.name" value="value">相等<else/>不相等</eq>
通常比较标签的值是一个字符串或者数字,如果需要使用变量,只需要在前面添加“$”标志:
当vo对象的属性等于$a就输出
<eq name="vo:name" value="$a">{$vo.name}</eq>
所有的比较标签可以统一使用compare标签(其实所有的比较标签都是compare标签的别名),例如:
当name变量的值等于5就输出
<compare name="name" value="5" type="eq">value</compare>
等效于 <eq name="name" value="5" >value</eq>
其中type属性的值就是上面列出的比较标签名称
Range标签
Range标签用于判断某个变量是否在某个范围之内,包括in、notin和range三个标签。
可以使用in标签来判断模板变量是否在某个范围内,例如:
<in name="id" value="1,2,3" >输出内容1</in>
如果判断不再某个范围内,可以使用:
<notin name="id" value="1,2,3" >输出内容2</notin>
可以把上面两个标签合并成为:
<in name="id" value="1,2,3" >输出内容1<else/>输出内容2</in>
Value属性的值可以使用变量,例如:
<in name="id" value="$var" >输出内容1</in>
变量的值可以是字符串或者数组,都可以完成范围判断。
也可以直接使用range标签,替换in和notin的用法:
<range name="id" value="1,2,3" type="in" >输出内容1</range>
其中type属性的值可以用in或者notin。
Present标签
可以使用present标签来判断模板变量是否已经赋值,例如:
<present name="name">name已经赋值</present>
如果判断没有赋值,可以使用:
<notpresent name="name">name还没有赋值</notpresent>
可以把上面两个标签合并成为:
<present name="name">name已经赋值<else /> name还没有赋值</present>
Empty标签
可以使用empty标签判断模板变量是否为空,例如:
<empty name="name">name为空值</empty>
如果判断没有赋值,可以使用:
<notempty name="name">name不为空</notempty>
可以把上面两个标签合并成为:
<empty name="name">name为空<else /> name不为空</empty>
Defined标签
可以使用defined标签判断常量是否已经有定义,例如:
<defined name="NAME">NAME常量已经定义</defined>
如果判断没有被定义,可以使用:
<notdefined name="NAME">NAME常量未定义</notdefined>
可以把上面两个标签合并成为:
<defined name="NAME">NAME常量已经定义<else /> NAME常量未定义</defined>
IF标签
如果觉得上面的标签都无法满足条件判断要求的话,我们还可以使用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>
必须改成:
<if condition="$id lt 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(及其别名iterate)、switch、if、elseif、else、foreach、compare(包括所有的比较标签)、(not)present、(not)empty、(not)defined等标签都可以嵌套使用。例如:
<volist name="list" id="vo">
<volist name="vo['sub']" id="sub">
{$sub.name}
</volist>
</volist>
上面的标签可以用于输出双重循环。
默认的嵌套层次是3级,所以嵌套层次不能超过3层,如果需要更多的层次可以指定TAG_NESTED_LEVEL配置参数。
使用PHP代码
Php代码可以和标签在模板文件中混合使用,可以在模板文件里面书写任意的PHP语句代码 ,包括下面两种方式:
第一种是使用php标签:
<php>echo 'Hello,world!';</php>
第二种就是直接使用原始的php代码:
<?php echo 'Hello,world!'; ?>
但是php标签或者php代码里面就不能再使用标签(包括普通标签和XML标签)了,因此下面的几种方式都是无效的:
<php><eq name='name' value='value'>value</eq></php>
Php标签里面使用了eq标签,因此无效
<php>if( {$user} != 'ThinkPHP' ) echo 'ThinkPHP' ;</php>
Php标签里面使用了{$user}普通标签输出变量 ,因此无效。
<php>if( $user.name != 'ThinkPHP' ) echo 'ThinkPHP' ;</php>
Php标签里面使用了$user.name 变量输出 ,因此无效。
简而言之,在PHP标签里面不能再使用PHP本身不支持的代码。
原样输出
可以使用literal标签来防止模板标签被解析,例如:
<literal>
<if condition="$name eq 1 "> value1
<elseif condition="$name eq 2" />value2
<else /> value3
</if>
</literal>
上面的if标签被literal标签包含,因此if标签里面的内容并不会被模板引擎解析,而是保持原样输出。
Literal标签可以用于页面的JS代码外面,确保JS代码中的某些用法和模板引擎不产生混淆。
模板注释
模板支持注释功能,该注释文字在最终页面不会显示,仅供模板制作人员参考和识别。
格式:{/* 注释内容 */ } 或 {// 注释内容 }
说明:在显示页面的时候不会显示模板注释,仅供模板制作的时候参考。
注意{和注释标记之间不能有空格。
例如:
{// 这是模板注释内容 }
{/* 这是模板
注释内容*/ }
模板注释支持多行可以。模板注释在生成编译缓存文件后会自动删除,这一点和Html的注释不同。
引入标签库
前面我们所讲述的标签用法都是内置的标签库或者内置模板的用法,事实上,内置模板引擎的标签库是可以无限扩展和增加标签的,一旦你扩展和使用了新的标签库,就必须要告诉模板当前要使用的标签库名称,否则不会自动导入,防止以后标签库大量扩展后增加解析工作量,导入标签库使用tagLib标签。
格式:<tagLib name="标签库1[,标签库2,…]" />
可以同时导入多个标签库,用逗号分隔。
例如:
<tagLib name="html" />
表示在当前模板文件需要引入html标签库。要引入标签库必须确保有Html标签库的定义文件和解析类库(如何扩展这种方式请参考前面的标签库扩展部分)。Cx标签库内置导入,无需使用taglib标签导入。
引入后,html标签库的所有标签在当前模板页面中都可以使用了。外部导入的标签库必须使用标签库前缀的xml标签,避免两个不同的标签库中存在同名的标签定义,例如(假设Html标签库中已经有定义select和link标签):
<html:select options='name' selected='value' />
<html:link href='/path/to/common.js' />
标签库使用的时候忽略大小写,因此下面的方式一样有效:
<HTML:LINK HREF='/path/to/common.js' />
如果你的每个模板页面都需要加载Html标签库的话,也可以通过配置直接预先加载Html标签库。
'TAGLIB_PRE_LOAD' => 'html' ,
如果有多个标签库需要预先加载的话,用逗号分隔。定义之后,每个模板页面都可以直接使用:
<html:select options='name' selected='value' />
而不需手动引入Html标签库。
假设你确信Html标签库无论在现在还是将来都不会和系统内置的标签库存在相同的标签,那么可以配置TAGLIB_BUILD_IN的值把Html标签库作为内置标签库引入,例如:
'TAGLIB_BUILD_IN' => 'cx,html' ,
这样,也无需在模板文件页面引入Html标签库了,并且可以不带前缀直接使用Html标签库的标签:
<select options='name' selected='value' />
注意,cx标签库是系统内置标签库,不能删除定义。
修改定界符
模板文件可以包含普通模板标签和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模板标签,ThinkPHP包含了一个基于XML和TagLib技术的模板标签,包含了普通模板有的功能,并且有一些方面的增强和补充,更重要的一点是新的标签库模板技术更加具有扩展性。新的TagLib标签库具有命名空间功能,ThinkPHP框架内置了CX标签库。如果你觉得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标签和普通标签的定界符不能冲突,否则会导致解析错误。
XML模板标签可以用于模板变量输出、文件包含、模板注释、条件控制、循环输出等功能,而且完全可以自己扩展功能。