dedeCMS模板原理

勾子技术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. ?
  19. 在以上例子中,比较不好理解的是两个 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. //解析通用的 field 标签 [1]*
    23. if($tagname=='field')
    24. {
    25. $vname = $ctag->GetAtt('name');
    26. if(isset($refObj->Fields[$vname]))
    27. {
    28. $dtp->Assign($tagid, $refObj->Fields[$vname]);
    29. }
    30. else if( isset( $this->TypeLink->TypeInfos[$vname] ) )
    31. {
    32. $dtp->Assign($tagid, $this->TypeLink->TypeInfos[$vname]);
    33. }
    34. continue;
    35. }
    36. //同名标记(兼容旧版)处理
    37. if(ereg("^(artlist|likeart|hotart|imglist|imginfolist|coolart|specart|autolist)$",$tagname))
    38. {
    39. $tagname='arclist';
    40. }
    41. if($tagname=='friendlink')
    42. {
    43. $tagname='flink';
    44. }
    45. //给不同的标记调用不同的解析文件 [2]*
    46. if(in_array($tagname,$alltags))
    47. {
    48. $filename = DEDEINC.'/taglib/'.$tagname.'.lib.php';
    49. include_once($filename);
    50. $funcname = 'lib_'.$tagname;
    51. $dtp->Assign($tagid,$funcname($ctag,$refObj));
    52. }
    53. }
    54. }
    55. 以上代码的重点就是 [1] [2] 标注的地方

      [1]是解析文档中field标签,这个标签对于文档类中,都必使用 var Fields; 数组来表示这些通用文档字段,但对于不同模板,它的值也是可变的。

      [2]就是勾子技术的关键,给field以及系统标记以外的标记调用不同的具体解析代码,这里规定了这些代码必须放在include/taglib文件夹内,名称为“标记名.lib.php”,而这个文件里定义的接口函数格式为:

      以下为引用的内容:

      1. <?php
      2. if(!defined('DEDEINC'))
      3. {
      4. exit("Request Error!");
      5. }
      6. function lib_标记名称(&$ctag,&$refObj)
      7. {
      8. global $dsql,$envs;
      9. //属性处理
      10. $attlist="row|12,titlelen|24";
      11. FillAttsDefault($ctag->CAttribute->Items,$attlist);
      12. extract($ctag->CAttribute->Items, EXTR_SKIP);
      13. $revalue = '';
      14. //你需编写的代码,不能用echo之类语法,把最终返回值传给$revalue
      15. //------------------------------------------------------
      16. $revalue = 'Hello Word!';
      17. //------------------------------------------------------
      18. return $revalue;
      19. }
      20. ?>
      21. 到这里就完全揭开了DedeCms V5.3勾子技术的真正面目,上面还有一个没交待清楚的是

        “$dtp->refObj = null;” 这个地方,其实对于Dedecms的文档解析类,100%都是面向对象的,它在类里通常是写为

        “$this->dtp->refObj = $this;” 这个对象正是 function lib_标记名称(&$ctag,&$refObj) 里的第二个参数,说到这里,有点明白它的作用了吧,简单的来说就是在接口函数里获取当前解析类的一些相关信息,这是相当有用的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值