在上一节中,我们知道模板元素的一种:模板变量,并知道如何在程序中给它赋值,使之呈现我们想要的东西.这对一般的简单网页来说,或许就已经够用了.现在我们设想一稍微复杂的一种情况,在template目录下新建一个second.html模板文件,内容为:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> 我的第二个模板文件 </TITLE> </HEAD> <BODY> 下面是一个列表 <UL> <li>张三 的成绩是 82 <li>李四 的成绩是 90 <li>王儿 的成绩是 60 <li>麻子 的成绩是 77 </UL> </BODY> </HTML>
上面的列表中列出了"张三","李四","王二","麻子"四人的成绩.假设要用PHP代码嵌入HTML的方式输出的话,你可能是这样写的:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> 我的第二个模板文件 </TITLE> </HEAD>
<BODY> 下面是一个列表 <?php $result = mysql_query("SELECT username,score FROM my_tbl"); ?> <UL> <?php while ($row = mysql_fetch_array($result)) { ?> <li><?=$row["username"]?> 的成绩是 <?=$row["score"]?> <?php } ?> </UL> </BODY> </HTML>
这样写很适合PHP新手,但你很快发现你或者美工改这个列表样式的时候需要多么的小心翼翼,特别是美工,如果他不懂你写得PHP代码,那么他会终日生在恐惧之中!因为稍微的不小心,可能就会带来程序的运行错误.而且如果他想把这个列表从一个地方移到另一个地方,也是相当不容易的.于是作为程序员的你不得不把美工(虽然你做的可能性更大)修饰过的页面重新审查一次,无形中就造成费时费力。
现在好了,有了Template模板类,你可以把你的代码从模板中抽取出来了.你可能会这样修改second.html模板:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> 我的第二个模板文件 </TITLE> </HEAD>
<BODY> 下面是一个列表 <UL> <li>{username1} 的成绩是 {score1} <li>{username2} 的成绩是 {score2} <li>{username3} 的成绩是 {score3} <li>{username4} 的成绩是 {score4} </UL> </BODY> </HTML>
显然,你采取了一个良好的命名方式,用1,2,3..来表示每一行数据,然后你在你的程序里循环给这些变量赋值,也是不难的,比如:(second.php)
<?php //包含进模板类 template.inc require "inc/template.inc";
//创建一个实例 $tpl = new Template("template");
//将整个文件读进来 $tpl->set_file("main", "first.html");
//连接数据库,选择数据库略 省略.....
//查询结果 $result = mysql_query("SELECT username,score FROM my_tbl");
//给文件中的模板变量赋值 $i=0; while ($row = $idb->fetch_array($result)) { $i++; $tpl->set_var("username" . $i, $row["username"]); $tpl->set_var("score" . $i, $row["score"]); }
//完成替换 $tpl->parse("mains", "main");
//输出 $tpl->pparse("mains", "main");
?>
这样你也能得到正确结果.在特殊情况下你或许需要这样做.但Template提供了一个更方便的"大的模板变量",那就是块.我之所以称之为"大的模板变量",是因为它也可以视为可以包含其他模板变量的变量.形式如
<UL> <!-- BEGIN list --> <li>{username} 的成绩是 {score} <!-- END list --> </UL>
即用<!-- BEGIN 块名称 -->和<!-- END 块名称 -->定义了一个名为list的块,(注意:我在这里为了方便理解,只称之为块名称).这个块里面又包含一些HTML代码(<li>等等)以及模板变量({username},{score}).
在讲述如何用块输出列表之前,我们先谈一下块的定义格式.
首先<!-- BEGIN list -->和<!-- END list --> 都要各自为一行,亦即下面的块的定义是错误的 1,
同行的 <!-- BEGIN list --> <li>{username} 的成绩是 {score} <!-- END list --> 2,
<!-- BEGIN list --> <li>{username} 的成绩是 {score} <!-- END list --> 同行的
<!--和-->都是固定的,也就是说只能是两个中划线("-"),且它们与BEGIN list之间都至少有一个空(空格或tab),看下面的例子
<!--BEGIN list --> <!-- BEGIN list--> 它们都是错误的块的定义方法,因为第一个<!--与BEGIN之间至少应该有一个空,第二个-->与list之间至少有一个空.
BEGIN/END和list之间也应该有一个空格,注意是有且仅有一个空格,不能多也不能少.
块的名称建议你只使用字符,数字,下划线以及它们的组合.
BEGIN和END两个词语都应该是大写的。
好了,下面开始探讨如何是这个块变成一个列表.我们可以这样
<?php //包含进模板类 template.inc require "inc/template.inc";
//创建一个实例 $tpl = new Template("template");
//将整个文件读进来 $tpl->set_file("main", "second.html");
//加载块list $tpl->set_block("main", "list", "lists");
//连接数据库,选择数据库略 省略.....
//查询结果 $result = mysql_query("SELECT username,score FROM my_tbl");
//给文件中的模板变量赋值 while ($row = $idb->fetch_array($result)) { $tpl->set_var("username", $row["username"]); $tpl->set_var("score", $row["score"]); $tpl->parse("lists", "list", true); }
//完成替换 $tpl->parse("mains", "main");
//输出 $tpl->pparse("mains", "main");
?>
记住把你的数据库连接写在我省略的部分,就可以打印正确的结果,一如
下面是一个列表
- 张三 的成绩是 82
- 李四 的成绩是 90
- 王儿 的成绩是 60
- 麻子 的成绩是 77
|
可以看到在PHP代码里有两个东西
$tpl->set_block("main", "list", "lists"); //代码1 $tpl->parse("lists", "list", true); 就不可思议的将整个块循环输出了.代码1用来加载模板main中的块list,并给其一个名字lists,list就是模板中的一个大变量,它的内容就是<li>{username} 的成绩是 {score}即:
"list" = "<li>{username} 的成绩是 {score}" 之所以用lists命名,是为了程序的可读性,也就是说我很容易就知道XXXs是XXX块的名称.
使用set_block后,模板中的块内容
<!-- BEGIN list --> <li>{username} 的成绩是 {score} <!-- END list --> 就被lists代替了.于是我们的模板就变成了
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> 我的第二个模板文件 </TITLE> </HEAD>
<BODY> 下面是一个列表 <UL> {lists} </UL> </BODY> </HTML>
块变成了一个变量(lists)!下面只要将lists变量替换成我们想要的就行了.
代码二所处的循环
while ($row = $idb->fetch_array($result)) { $tpl->set_var("username", $row["username"]); $tpl->set_var("score", $row["score"]); $tpl->parse("lists", "list", true); //代码2 } 每一次循环,两个set_var分别给username,score赋值,然后"list"就变成了 "list" = "<li>具体的名字 的成绩是 具体的分数" 代码2就是将list分析后的内容赋给lists,这样就完成了整个块的分析.
parse第三个参数可以设置list中的值是直接存在lists里面,还是附加在原有值之后.我们这里设置为true,说明是附加在原有值之后,才得以每个list的值都会显示出来.反之设为false的话,后面的值会覆盖掉以前的值.最终的结果会是
综上所述,Template模板类的替换方式是: 1,用set_block将模板中的list块(或者你命名的其他块)替换成变量lists. 2,用set_var给list块中的变量赋值 3,把赋值并执行替换后的list内容依次给lists 4,完成分析

|