PHP开发必备 PHP模版引擎Dwoo深入学习

在上一篇关于Dwoo的教程中(PHP开发必备 一步步学PHP模版引擎Dwoo),我们讨论了Dwoo中的基本用法。在本文中,我们将进一步讲解在Dwoo中的一些高级用法,比如插件机制的编写以及如何跟常见的PHP框架整合。

一、Dwoo中模版的继承

Dwoo的其中一个强大功能是它可以支持模版的继承。这实现起来是十分简单的,只需要定义好一个父模版,然后子模版则可以继承父模版了,并且可以在子模版中定义多种新的特性。聪明的开发者会善于利用这个特性,去减少重复的劳动。

Dwoo中继承模版的关键在于“扩展”的插件机制,它允许模版去继承另外一个模版。为了更好地理解这一特性,我们举个例子说明如下。假设目前你已经有一个基类的模版,名字叫base.tpl,其中包含了两个区域,一个是导航区,一个是内容区,如下:

 
 
 
 
  1. <html> 
  2. <head></head> 
  3. <body>   
  4. {block "nav"}  
  5. {/block}  
  6. {block "content"}  
  7. <div id="content"> 
  8. This is content for the main page.  
  9. </div>   
  10. {/block}  
  11. </body> 
  12. </html> 

现在,假设你的一些页面需要使用水平导航条,你只需要继承基类模版页即可,并且可以重新定义导航条的样式,如下代码,我们把这个代码定义为child.tpl:

 
 
 
 
  1. {extends "base.tpl"}  
  2. {block "nav"}  
  3. <div id="nav">  
  4. <a href="#">Home</a> |   
  5. <a href="#">News</a> |  
  6. <a href="#">Weather</a> |  
  7. <a href="#">Hotels</a> |  
  8. <a href="#">Dining</a>  
  9. </tr>  
  10. </table>  
  11. </div>  
  12. {/block

这里使用了{extends “base.tpl”}指出是继承了父类的模版,并且在这里的{block “nav”}区域中,重写了导航条的内容,最后输出为如下图:

现在我们考察另外一种情况,假设一些页面中需要额外的子导航菜单,比如需要以垂直形式显示导航条,这时,我们可以采用如下代码:

 

 
 
 
 
  1. {extends "child.tpl"}  
  2. {block "nav"}  
  3. {$dwoo.parent}  
  4. <div id="sub-nav">  
  5. <h2>{$subtitle}</h2>  
  6. <ul>  
  7. {loop $items}  
  8. <li><a href="#">{$item}</a></li>   
  9. {/loop}  
  10. </ul>  
  11. </div>   
  12. {/block}  
  13. {block "content"}  
  14. <div id="content">  
  15. This is content for the Dining page.  
  16. </div>  
  17. {/block

在这里,使用了{$dwoo.parent}去调用了父类模版,注意这里是继承了child.tpl这个模版,也就是说,调用了父类模版中的导航条中的内容,并且这里又重新定义了一个垂直的导航条,注意这里还重写了content区域的内容,覆盖了父模版中对应的content区域的内容了,结果如下图:

可以看到,只要适当使用模版继承,则可以大大方便开发。

#p#

二、子模版

Dwoo支持子模版,这些子模版使得开发者可以在应用中重用它们。子模版的创建方法是使用标签{template}….{/template},其中要提供唯一的名称,以便在其他地方进行引用。而在其他地方引用子模版,可以使用”load template”标签加载。

子模版中可以传递多个参数,下面直接看例子以方便理解。首先编写一个子模版,名称叫slave.tpl,代码如下:

 
 
 
 
  1. {template mylist data}  
  2. <ul>  
  3. {foreach $data d}  
  4. <li>{$d}</li>  
  5. {/foreach}  
  6. </ul>  
  7. {/template} 

这里,我们把这个子模版命名为mylist,其中有一个循环取读取data变量中的值并输出。

有了子模版后,我们就可以在需要其的地方加载它,比如,在一个模版文件master.tpl中,可以这样调用:

 
 
 
 
  1. {load_templates "slave.tpl"}  
  2. {mylist $items

这里用load_templates加载slave.tpl的子模版,并且为子模版mylist赋值items变量,而items变量可以由如下代码去赋值:

 
 
 
 
  1. <?php  
  2. include 'dwooAutoload.php';  
  3. try {  
  4. $dwoo = new Dwoo();  
  5. $tpl = new Dwoo_Template_File('tmpl/master.tpl');  
  6. $data = array();   
  7. $data['items'] = array('red''blue''green''yellow');;  
  8. $dwoo->output($tpl$data);  
  9. } catch (Exception $e) {  
  10. echo "Error: " . $e->getMessage();   
  11. }  
  12. ?> 

可以看到输出如下:

可以看到,子模版的确十分方便使用,而且子模版中的内容一旦变更,其他所有用到子模版地方的内容也会接着变化。

#p#

三、编写自己的插件

Dwoo中的一个前大功能是能可以让开发者编写插件,并通过Dwoo的addplugin机制加载自己写的类,现举一个简单例子说明。比如下面的代码,封装了对email的操作:

 
 
 
 
  1. <?php  
  2. function fix_address(Dwoo $dwoo$str) {  
  3. return str_replace(  
  4. array('@''.''-'),   
  5. array(' at '' dot '' dash '),   
  6. $str 
  7. );  
  8. }  
  9. include 'dwooAutoload.php';  
  10. try {  
  11. $dwoo = new Dwoo();  
  12. $tpl = new Dwoo_Template_File('tmpl/plugin.tpl');  
  13. $dwoo->addPlugin('email_safe''fix_address');  
  14. $data['string']= '[email protected]';  
  15. $dwoo->output($tpl$data);  
  16. } catch (Exception $e) {  
  17. echo "Error: " . $e->getMessage();   
  18. }  
  19. ?> 

在这个例子中,我们想将用户EMAIL中的象@,分隔符等符号用英文替换掉,这样防止象网上机器人等去采集EMAIL,泄露私隐。其中fix_address方法为替换的方法。而通过dwoo中的addPlugin方法,命名一个插件,名字为email_safe,而插件的内容则指定为fix_address方法。在使用这个插件时,可以如下使用,plugin.tpl内容为:

 
 
 
 
  1. {email_safe($string)} 

下图为输出结果:

而另外一种使用dwoo插件的方法为继承Dwoo_Filter abstract class,如下:

 
 
 
 
  1. <?php  
  2. class Dwoo_Plugin_email_safe extends Dwoo_Plugin  
  3. {   
  4. public function process($email)  
  5. {  
  6. return str_replace(  
  7. array('@''.''-'),   
  8. array(' at '' dot '' dash '),   
  9. $email 
  10. );  
  11. }  
  12. }  
  13. ?> 

如果用这种方式的话,则可以把该文件保存在dwoo目录下的plugins目录下,则dwoo的自动加载机制会自动加载这个插件,而不用每次使用时都使用addplugin的功能。

#p#

四、DWOO的过滤器

同样,dwoo中也支持用户编写过滤器,它可以在模版内容向用户输出前进行一些相关的操作,跟插件类似,可以使用addFilter()加载自己编写的过滤器,例子如下:

 
 
 
 
  1. <?php  
  2. function activate_mailto_links(Dwoo $dwoo$str) {  
  3. return preg_replace('/([a-zA-Z0-9]+@[a-zA-Z0-9._-]+\.[a-zA-Z]+)/''<a href="mailto:$1">$1</a>'$str);  
  4. }  
  5. include 'dwooAutoload.php';  
  6. try {  
  7. $dwoo = new Dwoo();  
  8. $dwoo->addFilter('activate_mailto_links');  
  9. $tpl = new Dwoo_Template_File('tmpl/filter.tpl');  
  10. $data['string']= 'Press enquiries: [email protected] or call 1-800-1234. General inquiries: [email protected].';  
  11. $dwoo->output($tpl$data);  
  12. } catch (Exception $e) {  
  13. echo "Error: " . $e->getMessage();   
  14. }  
  15. ?> 

这个例子的过滤器中,作用是自动把模版合成输出后的内容中的含有的邮件地址自动加上mailto:的邮件链接。结果如下输出:

同样,也可以这样写:

 
 
 
 
  1. <?php  
  2. class Dwoo_Filter_activate_mailto_links extends Dwoo_Filter  
  3. {   
  4. public function process($str)  
  5. {  
  6. return preg_replace('/([a-zA-Z0-9]+@[a-zA-Z0-9._-]+\.[a-zA-Z]+)/''<a href="mailto:$1">$1</a>'$str);  
  7. }  
  8. }  
  9. ?> 

把该文件保存在dwoo下的plugins目录中,同样DWOO会自动加载。

#p#

五、DWOO中的缓存

Dwoo中已经内置了很好的缓存功能,大大提高了效率,下面讲解使用dwoo缓存的步骤:

1. 在Dwoo_Template_File的构造函数中,设定cache的名称和缓存时间。

2. 在isCached()方法中,编写相关的模版生成代码,并且当缓存存在的时候,直接返回缓存中的页面。

下面举一个搜索Twitter中信息的例子来说明如何使用缓存:

 
 
 
 
  1. <html> 
  2. <head> 
  3. <style type="text/css">...  
  4. div.outer {...}{  
  5. border-bottom: dashed orange 1px;  
  6. padding: 4px;  
  7. clear: both;  
  8. height: 50px;  
  9. }   
  10. div.img {...}{  
  11. float:left;  
  12. padding-right: 2px;  
  13. }  
  14. span.attrib {...}{  
  15. font-style: italic;  
  16. }  
  17. </style>   
  18. </head> 
  19. <body> 
  20. <h2>{$title}</h2> 
  21. {loop $records}  
  22. <div class="outer"> 
  23. <div class="img"><img width=48" height="48" src="{$image}" /></div> 
  24. <div>{$tweet} <br/> <span class="attrib">By <a href="{$uri}">{$owner}</a> on {$time}</span></div> 
  25. </div>   
  26. {/loop}  
  27. </body> 
  28. </html> 

上面的模版是循环输出在Twitter中检索输出的微博内容。接下来看处理模版的PHP程序,如下:

 

 
 
 
 
  1. <?php  
  2. include 'dwooAutoload.php';  
  3. $dwoo = new Dwoo();  
  4. $tpl = new Dwoo_Template_File('tmpl/tweets.tpl', 120, 'id_g75430i472j');  
  5. //检查缓存中是否已经存在该文件,存在的话,从缓存中显示  
  6. if ($dwoo->isCached($tpl)) {  
  7. $dwoo->output($tplarray());  
  8. echo '(cached output)';  
  9. else {  
  10. //缓存中不存在,直接搜索twitter   
  11. $result = simplexml_load_file('http://search.twitter.com/search.atom?q=pasta&lang=en');  
  12. $records = array();  
  13. foreach ($result->entry as $entry) {  
  14. $item['image'] = (string)$entry->link[1]['href'];   
  15. $item['owner'] = (string)$entry->author->name;  
  16. $item['uri'] = (string)$entry->author->uri;  
  17. $item['tweet'] = (string)$entry->content;  
  18. $item['time'] = date('d M Y, h:i'strtotime($entry->published));   
  19. $records[] = $item;  
  20. }  
  21. $data = new Dwoo_Data();  
  22. $data->assign('records'$records);  
  23. $data->assign('title'$result->title);  
  24. $dwoo->output($tpl$data);   

上面的PHP代码中,首先是用isCached()方法,判断缓存中是否有该文件,如果有的话则直接读取缓存中已经合成好的页面文件显示给用户,否则的话调用twitter的Atom公开API接口去查询关键字pasta,再输出到页面。输出结果如下图:

同时注意,$tpl = new Dwoo_Template_File('tmpl/tweets.tpl', 120, 'id_g75430i472j');中,第2个参数是缓存的过期时间,为120秒,第3个参数是缓存的名称,而且该名称在应用中必须是唯一的。

【编辑推荐】

  1. PHP开发程序应该注意的42个优化准则
  2. PHP正则表达式 PHP中的正则函数
  3. PHP程序员突破成长瓶颈
  4. PHP中几个常用的时间应用方式
免责声明:文章内容不代表本站立场,仅供读者参考。产品相关技术问题请发送工单。 本文链接:https://www.idc.net/help/387685/

为您推荐

开源数据收集引擎 Logstash 讲解和示例讲解

一、概述 Logstash 是一个开源的数据收集和日志处理工具,它是 Elastic Stack(ELK Stack)的一部分,用于从各种数据源中采集、转换和传输数据,以帮助分析和可视化大规模数据。Logstash 通常与 Elasticsearch 和 Ki...

八个开源免费单点登录(SSO)系统

单点登录(SSO)是一个登录服务层,通过一次登录访问多个应用。使用SSO服务可以提高多系统使用的用户体验和安全性,用户不必记忆多个密码、不必多次登录浪费时间。 下面推荐一些市场上最好的开源SSO系统,可作为商业SSO替代。 1.Authelia https://github.com/authelia/authelia ...

浅谈HBase数据结构和系统架构

Part 01 LSM树模型 常见的的关系型数据库,如MySQL、SQL Server、Oracle等,使用B+ Tree作为数据存储与索引的基本结构,非叶子节点只存放索引数据,叶子节点存放所有数据和指向相邻节点的指针,具有高效的范围查询和稳定的查找效率,以及具有较小的读放大和空间放大。采用磁盘随机读写方式,且以磁盘数...

微软Radius平台重构现代应用程序部署

微软的 Azure 孵化团队日前推出一个叫 Radius 的新应用平台。Radius 平台可用于在 Kubernetes、公共云和边缘环境中运行各种现代应用程序。 Radius 是一个开源项目,最初支持的应用程序运行时包括Kubernetes、Azure和AWS,以后还会支持诸如谷歌云平台等云环境。 Mark Russ...

Ext JS3.0正式版发布

Ext JS3.0在经历数次RC版之后,extjs.com终于发布3.0的正式版。总体而言,较2.0改进不大,依然还是原理的组件模型,具体更新及改进如下: ◆提供了参照DWR后与后台的通讯包Direct,支持具有明显的REST风格的CRUD服务 ◆一系列的新的组件和例子,包括有图表(Charting, By YUI F...
返回顶部