用smarty后的印象以及感慨……
对Smarty的印象一直好坏各半,特性丰富得一塌糊涂,做为一个模板类,居然都快发展出一套模板语言了,而且还可以写插件,属于重型的东西,我对重型的东西一向是不轻易碰的。而且我以往写php,注意力都是放在功能上,对于界面得过且过。 最近的活比较要求界面,虽然没谁要求我用Smarty,但是我向来喜欢在工作中加入一些自己从来没有用过的东西或者写法,这样多少可以保持一些探索和学习的乐趣,不至于枯燥的重复。 开始本来是打算用SmartTemplate,H大写的文档很有用(可以偷懒,嘿嘿),结果发现SmartTemplate的主页都没有维护了,连个下载的地方都找不到,觉得还是有php.net支持的Smarty靠得住,虽然一直感觉重型了点,但本来就是准备找新鲜找刺激嘛,特性多可以玩的就多。 到google上搜刮了一通,找了几篇说得还比较清楚点的Smarty文章浏览了一下(国内大家都是转来转去,其实也只有几篇),另外还找到了Smarty的中文手册。 我先弄了个Smarty_Common类 <?php require_once 'Smarty.class.php'; class Smarty_Common extends Smarty{ function Smarty_Common(){ require_once ROOT_PATH .'includes/functions/smarty_insert.func.php'; $this->Smarty(); $this->template_dir = SMARTY_TEMPLATE; $this->compile_dir = SMARTY_COMPILE; $this->config_dir = SMARTY_CONFIG; $this->cache_dir = SMARTY_CACHE; $this->caching = 2; $this->compile_check = SMARTY_COMPILE_CHECK; $this->force_compile = SMARTY_FORCE_COMPILE; $this->left_delimiter = SMARTY_LEFT_DELIMITER; $this->right_delimiter = SMARTY_RIGHT_DELIMITER; } }
//smarty_insert.func.php保存Smarty的insert函数,了解Smarty的人应该会知道是个什么东西 ?>
SMARTY_开头的常量都是在config.inc.php里声明的 <?php //----------------------- SMARTY --------------------------// define('SMARTY_TEMPLATE', ROOT_PATH .'_templates/'); define('SMARTY_COMPILE', ROOT_PATH .'_templates_c/'); define('SMARTY_CONFIG', ROOT_PATH .'_configs/'); define('SMARTY_CACHE', ROOT_PATH .'_cache/'); define('SMARTY_LEFT_DELIMITER', '<{'); define('SMARTY_RIGHT_DELIMITER', '}>'); define('SMARTY_COMPILE_CHECK', false); // 每次都检查模板变化,正式运行的时候应该设置为false define('SMARTY_FORCE_COMPILE', false); // 每次都强制编译,正式运行的时候应该设置为false ?>
接下来我打算搞定header和导航条,于是又做了两个类 <?php class Smarty_header extends Smarty_Common{ function Smarty_header(){ $this->assign('title', 'xxx网站'); } }
class Smarty_navbar extends Smarty_Common{ function Smarty_navbar(){ $this->assign('login_status', '登录 / 注册'); //..... } } ?>
嗯,如果你已经比较熟悉Smarty,看到这里肯定已经在笑了。这是偶刚开始的思考方式,而且我说过,对界面我一向是得过且过考虑得很少的。 我觉得header里边以后需要包含不同的css和js文件,如果就是一个模板的话,无法容纳那么多,不过做成一个类的话,我可以以后给Smarty_header加上诸如linkCss()或者addJs()之类的方法来进行控制。Smarty_navbar也是基于类似的考虑,因为根据登录状态不同,导航条上的某些东西是需要改变的。 我打算以后给header.tpl加个{css}或者{js}变量,以后就可以对这两方面进行控制了。 其它的所有模板,都给他们加上{header}和{navbar},最后我生成某个最终页面的时候就得这样干 <?php $Smarty = new Smarty_Common(); $Smarty_header = new Smarty_header(); $Smarty_navbar = new Smarty_navbar();
$Smarty->assign('header', $Smarty_header->fetch('header.tpl')); $Smarty->assign('navbar', $Smarty_navbar->fetch('navbar.tpl')); //...... $Smarty->display('xxx.tpl'); ?>
说实话,几乎是刚刚写完我就厌倦了,这不是我希望的编码方式,控制起来好累,header和navbar只是两个简单的部件而已。 适当的逃避问题是一个好办法,不同的css我根本就不打算考虑了。至于js,只有xajax需要一定声明在<head></head>内,我只要保留一个{xajax_javascript}就ok,需要的时候我就"$Smarty->assign('xajax_javascript', $xajax->getJavascript())",就算我不assign,它也不会给我添乱(我开始知道模板变量不一定非要assign不可了 ;-))。 <!-- 新的header.tpl --> {config_load file='header.conf'} <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>{#title#}</title> <link href="css/main_01.css" rel="stylesheet" type="text/css" /> {$xajax_javascript} </head> <body>
这样一改,我就可以丢开Smarty_header类,只要在其它模板中用{include file='header.tpl'}就可以搞定,嗯,感觉好点了。 导航条就稍微麻烦点,因为根据状态的不同要即时的改变,而且要注意不被Smarty的缓存干扰到。 <!-- 新的navbar.tpl中改变的部分 --> <ul> <li>{insert name='cart'}</li> <li>{insert name='order_status'}</li> <li>{insert name='discount_ticket'}</li> <li>{insert name='login_status'}</li> </ul>
原先的{cart}被换成了{insert name='cart'},这实际上是调用了我定义的函数insert_cart(),而且更棒的是这样的调用是绕开了缓存的,完全符合我的即时改变文字的目的。 <?php // 保存在smarty_insert.func.php,在Smarty_Common类被调用时包含 function insert_cart(){ // 根据购物篮状态显示文字的代码先不写,现在只要简单显示文字就ok return '购物篮 0 | 结帐'; } ?>
现在Smarty_navbar也可以踢开了,{include file='navbar.tpl'}就可以达到目的。 改成这个样子,我已经心满意足了(我从来没有说过我是个勤奋的人,嘿嘿)。需要的时候再说,之前只要知道什么地方找得到答案就好。 我使用Smarty经历了一种全新的开发方式,而且感觉还不错。关于Smarty居然自行发展出了一套模板语言的指责,我觉得没有原来想象的那么恐怖,因为如果你只用assign(),Smarty一样的可以为你干活,有天你觉得某个特性似乎还不错,那也可以拿来用,用什么和不用什么,完全不是必须的,所以只是给你提供了足够多的可行性,但不强迫你使用。
|