$total = 21000;
$tpl->assign(\?>
所以在 Smarty 中我们只要指定一次变量,剩下的交给模版自行决定即可。这样了解了
吗?这就是让模版自行决定变量呈现风貌的好处!
控制模版的内容
重复的区块
在 Smarty 样板中,我们要重复一个区块有两种方式: foreach 及 section 。而在程序中我们则要 assign 一个数组,这个数组中可以包含数组数组。就像下面这个例子:
首先我们来看 PHP 程序是如何写的:
test2.php:
require \
$array1 = array(1 => \苹果\菠萝\香蕉\芭乐\
$tpl->assign(\$array2 = array(
array(\array(\
array(\ array(\ array(\ $tpl->assign(\ $tpl->display(\ ?>
而模版的写法如下:
templates/test2.htm:
测试重复区块
利用 foreach 来呈现 array1
<{foreach item=item1 from=$array1}>
<{$item1}> <{/foreach}>
利用 section 来呈现 array1
<{section name=sec1 loop=$array1}>
<{$array1[sec1]}> <{/section}>
利用 foreach 来呈现 array2
<{foreach item=index2 from=$array2}>
<{foreach key=key2 item=item2 from=$index2}> <{$key2}>: <{$item2}> <{/foreach}>
<{/foreach}>
利用 section 来呈现 array1
<{section name=sec2 loop=$array2}> index1: <{$array2[sec2].index1}> index2: <{$array2[sec2].index2}> index3: <{$array2[sec2].index3}> <{/section}>
执行上例后,我们发现不管是 foreach 或 section 两个执行结果是一样的。那么两者到底有何不同呢?
第一个差别很明显,就是foreach 要以巢状处理的方式来呈现我们所 assign 的两层数组变量,而 section 则以「主数组[循环名称].子数组索引」即可将整个数组呈现出来。由此可知, Smarty 在模版中的 foreach 和 PHP 中的 foreach 是一样的;而 section 则是 Smarty 为了处理如上列的数组变量所发展出来的叙述。当然 section 的功能还不只如此,除了下一节所谈到的巢状资料呈现外,官方手册中也提供了好几个 section 的应用范例。
不过要注意的是,丢给 section 的数组索引必须是从 0 开始的正整数,即 0, 1, 2, 3, ...。如果您的数组索引不是从 0 开始的正整数,那么就得改用 foreach 来呈现您的资料。您可以参考官方讨论区中的此篇讨论,其中探讨了 section 和 foreach 的用法。
巢状资料的呈现
模版引擎里最令人伤脑筋的大概就是巢状资料的呈现吧,许多著名的模版引擎都会特意强调这点,不过这对 Smarty 来说却是小儿科。
最常见到的巢状资料,就算论譠程序中的讨论主题区吧。假设要呈现的结果如下:
公告区
站务公告
文学专区
好书介绍
奇文共赏
计算机专区
硬件外围
软件讨论
程序中我们先以静态资料为例:
test3.php:
require \$forum = array(
array(\公告区\\
array(\站务公告\ )
),
array(\文学专区\ \
array(\好书介绍\ array(\奇文共赏\ ) ),
array(\计算机专区\ \
array(\硬件外围\ array(\软件讨论\ ) ) );
$tpl->assign(\ $tpl->display(\ ?>
模版的写法如下:
templates/test3.htm:
<{section name=sec2 loop=$forum[sec1].topic}>
<{/section}>
<{/section}>
执行的结果就像笔者举的例子一样。
因此呢,在程序中我们只要想办法把所要重复值一层一层的塞到数组中,再利用 <{第一层数组[循环1].第二层数组[循环2].第三层数组[循环3]. ... .数组索引}> 这样的方式来显示每一个巢状循环中的值。至于用什么方法呢?下一节使用数据库时我们再提。
转换数据库中的资料
上面提到如何显示巢状循环,而实际上应用时我们的资料可能是从数据库中抓取出来的,所以我们就得想办法把数据库的资料变成上述的多重数组的形式。这里笔者用一个 DB 类别来抓取数据库中的资料,您可以自行用您喜欢的方法。
我们只修改 PHP 程序,模版还是上面那个 (这就是模版引擎的好处~),其中 $db 这个对象假设已经在 main.php 中建立好了,而且抓出来的资料就是上面的例子。
test3.php:
require \
// 先建立第一层数组 $category = array();
$db->setSQL($SQL1, 'CATEGORY');
if (!$db->query('CATEGORY')) die($db->error());
// 抓取第一层循环的资料
while ($item_category = $db->fetchAssoc('CATEGORY')) {
// 建立第二层数组 $topic = array();
$db->setSQL(sprintf($SQL2, $item_category['category_id']), 'TOPIC'); if (!$db->query('TOPIC')) die($db->error()); // 抓取第二层循环的资料
while ($item_topic = $db->fetchAssoc('TOPIC')) {
// 把抓取的数据推入第二层数组中
array_push($topic, $item_topic); }
// 把第二层数组指定为第一层数组所抓取的数据中的一个成员 $item_category['topic'] = $topic; // 把第一层数据推入第一层数组中
array_push($category, $item_category); }
$tpl->assign(\$tpl->display(\
?>
在数据库抓取一笔资料后,我们得到的是一个包含该笔数据的数组。透过 while 叙述及 array_push 函式,我们将数据库中的资料一笔一笔塞到数组里。如果您只用到单层循环,就把第二层循环 (红色的部份) 去掉即可。
决定内容是否显示
要决定是否显示内容,我们可以使用 if 这个语法来做选择。例如如果使用者已经登入的话,我们的模版就可以这样写:
<{if $is_login == true}> 显示使用者操作选单 <{else}>
显示输入帐号和密码的窗体 <{/if}>
要注意的是,「==」号两边一定要各留至少一个空格符,否则 Smarty 会无法解析。