• 手把手带你认识DedeCms模板的勾子技术
    时间:2009-04-07   作者:佚名   出处:互联网

    勾子技术DedeCms V5.3最大的改变之一,可能大家不大理解勾子这名称,说具体些,在DedeCms里有很多模板调用标签,实际上,这些标签是通过解析后,按不同名称和属性返回不同内容来替代的,在不使用模板引擎的情况下,一个函数调用就可以认为是勾子的一种体现,这也是一些论坛程序的做法,但这种做法始终需要在核心一些文件加入一些代码,即使是最简单的代码,对升级显然是有一定麻烦的,而DedeCms V5.3的勾子技术则改变了这种做法,它的原理与一些框架的MVC机制类似,不过它不是动态产生触发器,而是动态解析标签。

    什么是动态解析标签?简单的来说就是模板里存在什么标记就调用什么代码去解析,这样不必要载入一些多余的代码,而且扩展更加灵活,在具体说明前,先用一个例子简单说明DedeCms模板引擎的使用。

    以下示例代码可以放在安装了dedecms系统的根目录中使用。

    以下为引用的内容:

    1. <?php
    2. //引入必须文件
    3. require_once(dirname(__FILE__)."/include/commin.inc.php");
    4. require_once(dirname(__FILE__)."/include/channelunit.func.php");
    5. require_once(dirname(__FILE__)."/include/dedetag.class.php");
    6. //初始化模板类
    7. $dtp = new DedeTagParse();
    8. $dtp->SetNameSpace("dede","{","}");
    9. //引用当前类([1]这里为空,后面会说明用途)
    10. $dtp->refObj = null;
    11. //载入模板
    12. $dtp->LoadTemplet($filename);
    13. //动态解析 include/taglib 里的标签 [2]
    14. MakeOneTag($dtp, null);
    15. //解析系统标签,显示内容
    16. $dtp->Display();
    17. //类似方法:GetResult() 获得解析后的HTML,SaveTo($filename)保存为文件
    18. ?

    在以上例子中,比较不好理解的是两个 null,其实如果在类中调用这模板类,通常表示为 $this

    具体原因需要分析 channelunit.func.php 里的

    MakeOneTag(&$dtp,&$refObj)

    这个函数的第一个参数不用说都知道是模板类本身的对象实例,如$refObj就是引入这个模板类的类,在Dedecms中,凡是 include/arc. 开头的文件都是这种文档解析类的具体功能类。

    它的具体代码如下:

    以下为引用的内容:
    1. function MakeOneTag(&$dtp,&$refObj)
    2. {
    3.         $alltags = array();
    4.         //读取自由调用tag列表
    5.         $dh = dir(DEDEINC.'/taglib');
    6.         while($filename = $dh->read())
    7.         {
    8.                 if(ereg("\.lib\.",$filename))
    9.                 {
    10.                         $alltags[] = str_replace('.lib.php','',$filename);
    11.                 }
    12.         }
    13.         $dh->Close();
    14.         //遍历tag元素
    15.         if(!is_array($dtp->CTags))
    16.         {
    17.                 return '';
    18.         }
    19.         foreach($dtp->CTags as $tagid=>$ctag)
    20.         {
    21.                 $tagname = $ctag->GetName();
    22.                
    23.                 //解析通用的 field 标签 [1]*
    24.                 if($tagname=='field')
    25.                 {
    26.                         $vname = $ctag->GetAtt('name');
    27.                         if(isset($refObj->Fields[$vname]))
    28.                         {
    29.                                 $dtp->Assign($tagid, $refObj->Fields[$vname]);
    30.                         }
    31.                         else if( isset( $this->TypeLink->TypeInfos[$vname] ) )
    32.                         {
    33.                                 $dtp->Assign($tagid, $this->TypeLink->TypeInfos[$vname]);
    34.                         }
    35.                         continue;
    36.                 }
    37.                 //同名标记(兼容旧版)处理
    38.                 if(ereg("^(artlist|likeart|hotart|imglist|imginfolist|coolart|specart|autolist)$",$tagname))
    39.                 {
    40.                         $tagname='arclist';
    41.                 }
    42.                 if($tagname=='friendlink')
    43.                 {
    44.                         $tagname='flink';
    45.                 }
    46.                
    47.                 //给不同的标记调用不同的解析文件 [2]*
    48.                 if(in_array($tagname,$alltags))
    49.                 {
    50.                         $filename = DEDEINC.'/taglib/'.$tagname.'.lib.php';
    51.                         include_once($filename);
    52.                         $funcname = 'lib_'.$tagname;
    53.                         $dtp->Assign($tagid,$funcname($ctag,$refObj));
    54.                 }
    55.         }
    56. }

    网友留言/评论

    我要留言/评论