thinkphp3.1自定义模板标签嵌套实现

jerry thinkphp 2015年11月19日 收藏
thinkphp3.1自定义模板标签嵌套实现
之前做的自定义标签,属性里面读取不到上层标签的值,然后找了很多文档发现没有能解决的,然后就自己研究了一下,搞出来了,下面是方法,绝对能用,不能用我吃了它。
原理:外层标签获取标签内的标签,提取标签内字符串以及标签属性,发送给嵌套的标签类进行处理

模板调用方法

页面显示效果

废话不多说,看代码

首先关于taglib的标签制作我就不多说了,不懂的看我之前写的文档

http://www.90coder.com/php/2015/07/12/31.html

下面是外层标签的写法
  1. public function _channel($attr,$content){
  2.         $attr = $this->parseXmlAttr($attr);
  3.         //变量读取
  4.         $tid   = $attr['tid'];
  5.         $tid   = ($tid)?$tid:$_GET['gid'];
  6.         $row   = $attr['row'];
  7.         $pc       = $attr['pc'];
  8.         $load  = $attr['load'];
  9.         $limit = $attr['limit'];
  10.         $order = $attr['order'];
  11.         
  12.         /*
  13.             这里排序,读取条件什么的逻辑就不再细表,根据你自己的需求写
  14.         */
  15.         //读取数据
  16.         $list = M("diycate")->where($w)->limit($limit)->order($order)->select();
  17.         //对数据简单处理
  18.         for($i=0;$i<count($list);$i++){
  19.             $array[$i] = $list[$i];
  20.             $array[$i][i] = $i+1;
  21.             $array[$i]['arcurl'] = U('News/slist','gid='.$list[$i]['gid']);
  22.         }
  23.         //读取标签
  24.         preg_match_all('/\[channel:(.*?)\]/',$content,$arry); //读取标签
  25.         $tag = $arry[0]; //匹配标签
  26.         $key = $arry[1]; //标签字段
  27.         $str='';
  28.         for($i=0;$i<count($array);$i++)
  29.         {
  30.             $c = $content; //读取模板内容
  31.             //替换标签
  32.             foreach($tag as $k=>$v){
  33.                 //分割字符串,如果有函数那么执行函数后在输出
  34.                 $arr = explode('|',$key[$k]);
  35.                 $th = $array[$i][$arr[0]];
  36.                 if($arr[1]){
  37.                     $arr[1] = str_replace('###',$array[$i][$arr[0]],$arr[1]);
  38.                     $a = '$th'." =$arr[1]";
  39.                     eval($a.';');
  40.                 }
  41.                 $c = str_replace($v,$th,$c);
  42.                 /*
  43.                 重点来了,下面的函数指明了允许使用的标签,channel:为嵌套标签的关键字后面跟你之前定义标签名,第一个标签
  44.                 里面的变量为上放标签最后得到的字符串,后面要继承沿用上级函数变量,才能使用多个标签。
  45.                 */
  46.                 //嵌套标签
  47.                 $r = TagLib_XML('channel:catelist',$c);
  48.                 $r = TagLib_XML('channel:wdlist',$r);
  49.             }
  50.             $str.=$r;
  51.         }
  52.         return $str;
  53.     }
跟给标签配套的函数
  1. //标签引擎
  2. function TagLib_XML($tag,$content){
  3.     //检索标签
  4.     preg_match_all('/\<'.$tag.'(.*?)\>/',$content,$arry);
  5.     $tou  = $arry[0]; 
  6.     $attr = $arry[1];
  7.     $fot  = '</'.$tag.'>';
  8.     $tag = explode(':',$tag);
  9.     
  10.     //声明可用嵌套标签 这里定义所有可以使用的标签,格式 '标签class类'=> '标签' 注意这里的标签不能加下划线'_'
  11.     $tagset = array(
  12.         'TagLibCate' => 'catelist,cateinfo',
  13.         'TagLibWd'     => 'wdlist,wdinfo,wdpic,wdtjyd',
  14.     );
  15.     
  16.     //检测该标签是否可用
  17.     $obj = array_search_str($tag[1],$tagset); //这是一个自定义数组函数 查询字符串是否在数组中存在
  18.     if(!$obj){ return $content; break;} //这里检测是否可用
  19.     
  20.     //模板数据处理
  21.     $c = $content;
  22.     for($i=0; $i<count($tou);$i++){
  23.         /*找出要替换的标签例如
  24.         channel:catelist tid="[channel:gid]">
  25.         <a href="[tag:arcurl]">[tag:name]</a>
  26.         </channel:catelist>
  27.         */
  28.         $str = strstr($content,$tou[$i]); 
  29.         $str = str_replace($tou[$i],'',$str);
  30.         $str = strstr($str,$fot,true);
  31.         
  32.         //执行替换操作
  33.         $run = '$ceshi = new '.$obj.';$runstr = $ceshi->_'.$tag[1].'($attr['.$i.'],$str);';
  34.         eval($run.';');
  35.         $strstr = $tou[$i].$str.$fot;
  36.         $c = str_replace($strstr,$runstr,$c);
  37.         
  38.     }
  39.     return $c;
  40. }
  41. /*
  42.  *    查找数组中元素是否包含某个字符串,返回键
  43.  */
  44. function array_search_str($str,$arr){
  45.     foreach($arr as $k=>$v){
  46.         if(strstr($v,$str)){return $k;break;}
  47.     }
  48.     
  49. }
上面的代码有点功底的就可以看懂