一个封装很好的类对使用者(可能不是开发者本人)来说,最大的好处就是,你无需知道类内部是怎么运作的,只需知道如何利用它提供的接口做你想做的事情即可.所以,本文不打算具体讲述PHPLIB Template(以下简称Template)是如何将"元素"转换成"值"的,你需要了解的是"它能这样做",而不是"它为什么能这样做".
好了,下面我们就开始它的第一个应用了.
先在我们要测试的网站的目录下建两个文件夹inc和template.目录inc下放引用文件,比如类库,函数库等,这里我们就把template.inc放如该目录下.tempate下放模板文件,我们先建一个模板文件first.html,内容如下
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> 我的第一个模板文件 </TITLE>
</HEAD>
<BODY>
真想对你说:我爱你 {lover} ,但我却不敢说,因为我知道你爱的人是 {man}.
<P>
<font color="#0000FF">{author}</font> 于 {date}
</BODY>
</HTML>
用inc,template命名文件目录,都是我的个人习惯,你完全可以采取不同的方式.我用扩展名为.html的名称命名模板文件,是为了方便美工用frontpage或者dreamweaver修改,但这完全取决于你自己的习惯.
first.html模板中的{lover},{man},{author}可以称为"模板变量",用花括号({})把变量名称括住即组成一个模板变量.模板变量就是模板元素的一种。你可能会担心它的命名问题,其实除了空格(" "),回车换行("\r", "\n"),tab(\t)外它都被视为是正确的.所以
{your-lover}
也是正确的.这点有时可能会令你很痛苦,因为模板里的有些javascript代码可能无意间变没有了,比如
if(a>b){document.write("i love u");}
中的
{document.write("i love u");}
也被视为一个变量了.上面的代码在你选的模板处理方式下,可能会变成if(a>b){},从而导致javascript错误.为什么会"变没"了呢?稍后将做解释.
上面我们定义的三个变量{lover},{man},{author}的原因是,我们想随时改变它们的值.下面我们就来做这个工作.新建first.php文件,内容如下:
<?php
//包含进模板类 template.inc
require "inc/template.inc";
//创建一个实例
$tpl = new Template("template", "keep"); //注1
//将整个文件读进来
$tpl->set_file("main", "first.html"); //注2
//给文件中的模板变量赋值
$tpl->set_var("lover", "kiki"); //注3
$tpl->set_var("man", "ccterran"); //注4
$tpl->set_var("author", "iwind"); //注5
//完成替换
$tpl->parse("mains", "main"); //注6
//输出替换的结果
$tpl->p("mains"); //注7
?>
浏览器中浏览这个文件,你就会发现输出
真想对你说:我爱你 kiki ,但我却不敢说,因为我知道你爱的人是 ccterran.
iwind 于 {date}
这一切正如我们所期望的(除了{date}).注1
$tpl = new Template("template", "keep");
是创建一个Template类的实例对象.它有两个参数,都是可选的.
第一个参数是模板所在目录,如果不设置则为"."(即当前目录),由于我们刚才把模板文件first.html放到template下了,所以这里为template.注意它一般使用相对路径,如果你用相对于根目录(比如 /phplib/test/template)的路径,就会出现
Template Error: set_root: /phplib/test/template is not a directory.
Halted.
的错误.
第二个参数是指定模板类对"未完成处理"变量的处理方式,所谓"未完成处理"指的是模板变量未赋值,块未完成替换工作(下面一节将讲到它),它有三个值可选,分别为"keep","comment","remove":
如果设为"keep",这些变量将原封不动的保留下来.
如果设为"comment",那么会在报错的同时,将未完成处理的变量全部转换成HTML的注释.
如果设为"remove",未完成处理的变量便会被删除(这也是默认的情况).
所以在上面的例子中,我指定的是"keep",于是{date}因为未赋值,所以还保留着.而缺省的情况下是"remove",所以,如果我这样创建实例对象
$tpl = new Template("template", "remove");
或者
$tpl = new Template("template");
的话,输出就变成了
真想对你说:我爱你 kiki ,但我却不敢说,因为我知道你爱的人是 ccterran.
iwind 于
可以看出{date}被删除了.如果是
$tpl = new Template("template", "comment");
它的结果将是
真想对你说:我爱你 kiki ,但我却不敢说,因为我知道你爱的人是 ccterran.
iwind 于
看起来和"remove"方式一样,但查看源文件,我们会发现
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> 我的第一个模板文件 </TITLE>
</HEAD>
<BODY>
真想对你说:我爱你 kiki ,但我却不敢说,因为我知道你爱的人是 ccterran.
<P>
<font color="#0000FF">iwind</font> 于 <!-- Template variable date undefined -->
</BODY>
</HTML>
其中有<!-- Template variable date undefined -->的错误信息,告诉我们date变量未定义(赋值).
用"comment"或许对程序的调试很有帮助.
我们再回头看看
if(a>b){document.write("i love u");}
中
{document.write("i love u");}
会"变没"的问题,是因为模板类视之为模板变量,但你没有给它指定值(当然会没有),且你没有指定"keep"方式来处理未定义变量,所以它就被"remove"了.
所以在模板使用过程中应该多多注意这些问题.
注2是将一个模板文件加载进来,事实上你可以一次加载多个模板(在第四节将讲到这个问题).你可以想象
$tpl->set_file("main", "first.html");
把"first.html"内容给变量"main"(尽管很多人称之为"句柄",但本文决定不谈"句柄"),所以"main"的值就变成模板的内容了,包含着那些模板变量.
注3,注4,注5,是给模板变量赋值.值是什么,你自然可以随便定.比如你还可以
$tpl->set_var("lover", "kiki1");
$tpl->set_var("man", "ccterran1");
$tpl->set_var("author", "iwind_php");
你也可以一次完成给一列的变量赋值.这样
$tpl->set_var(
array("lover"=>"kiki", "man"=>"ccterran", "author"=>"iwind")
);
如果你想设置一个变量的值为空的话,可以
$tpl->set_var("man", "");
或者
$tpl->set_var("man");
注6,是执行将上面$tpl->set_var给模板变量指定的值替换掉模板中的模板变量这个操作,第一个参数即为模板分析的结果,也可以视为一个变量.
当然注7的 $tpl->p("mains"); 就将模板分析的结果如你所愿的输出啦.
喏,恭喜你,你的第一个模板类应用就完成了.你可能不小心弄错了哪个地方,模板类默认情况下会自动打印出错误提示的,根据这些提示,你就很容易就可以找出问题所在,在第6节将会具体讲到.