任何一个模板引擎的功能都不可能是为你量身定制的,具有一个良好的可扩展 机制也是模板引擎的另外一个考量,Smarty采用的是插件方法来实现扩展,ThinkTemplate由于采用了标签库技术,比Smarty提供了更为 强大的定制功能,和Java的TagLibs一样可以支持自定义标签库和标签,每个XML标签都有独立的解析方法,所以可以根据标签库的定义规则来增加和 修改标签解析规则。在ThinkTemplate中标签库的体现是采用XML命名空间的方式。
标签库由定义文件和解析类构成。每个标签库存在一个XML定义文件,用来定义标签库中的标签和属性。并且一个标签库文件对应一个标签库解析类,每个 标签就是解析类中的一个方法。例如,CX标签库的定义文件是cx.xml 位于ThinkTemplate/Template/Tags/目录下面,而cx标签库解析类文件是位于ThinkTemplate/Template /TagLib/目录下面的TagLibCx.class.php文件,每个标签的解析方法就是TagLibCx类的一个方法,为了不和系统的关键字冲 突,所以在方法名前加上了“_”前缀,因此,假如要定义Cx:Var 的标签解析,就需要定义一个 _var方法。
标签库解析类的作用其实就是把某个标签定义解析成为有效的模版文件(可以包括PHP语句或者HTML标签)。扩展标签库需要添加标签库定义XML文件和标签库解析类。
标签库定义XML文件的格式为:
1 <!--- XML/HTML代码 --> 2 <?xml version="1.0" encoding="UTF-8"?> 3 <taglib> 4 <tag> 5 <name>标签名称< /name> 6 <nested>是否允许嵌套< /nested> 7 <alias>标签别名< /alias> 8 <bodycontent>是否属于闭合标签< /bodycontent> 9 <attribute> 10 <name>属性名称< /name> 11 <required>是否必须< /required> 12 </attribute> 13 </tag> 14 </taglib>
标签库的名称和文件名一致,每个tag标签对定义了标签库中的一个标签,每个tag节点的属性定义规范如下:
name:标签名称
nested:是否允许标签嵌套(true或false)
alias:标签别名(多个逗号分隔)
bodycontent:是否为闭合标签(true或empty)
attribute:标签允许的属性
每个标签节点可以包含多个属性,也就是tag节点可以定义多个attribute节点,每个attribute属性支持两个属性:name和required,required(true或false)表示该属性是否为必须。
然后,我们看解析类的定义,每个标签的解析方法在定义的时候需要添加“_”前缀,可以传入两个参数,属性字符串和内容字符串(对于非闭合标签)。必须通过return 返回标签的字符串解析输出,在标签解析类中可以调用模板类的实例。下面是一个include解析方法的定义:
1 //PHP代码 2 public function _include($attr,$content){ 3 $tag = $this->parseXmlAttr($attr,'include'); 4 $file = $tag['file']; 5 return $this->tpl->parseInclude($file); 6 }
在每个标签的解析方法中,首先需要调用
1 //PHP代码 2 $this->parseXmlAttr($attr,'include');
表示分析某个标签的XML定义,返回include的所有标签属性。接下来就是根据具体的属性值来返回实际的解析内容了。