thinkphp3.1自定义模板标签嵌套实现
之前做的自定义标签,属性里面读取不到上层标签的值,然后找了很多文档发现没有能解决的,然后就自己研究了一下,搞出来了,下面是方法,绝对能用,不能用我吃了它。
原理:外层标签获取标签内的标签,提取标签内字符串以及标签属性,发送给嵌套的标签类进行处理
模板调用方法
页面显示效果
废话不多说,看代码
首先关于taglib的标签制作我就不多说了,不懂的看我之前写的文档
http://www.90coder.com/php/2015/07/12/31.html
下面是外层标签的写法
public function _channel($attr,$content){
$attr = $this->parseXmlAttr($attr);
//变量读取
$tid = $attr['tid'];
$tid = ($tid)?$tid:$_GET['gid'];
$row = $attr['row'];
$pc = $attr['pc'];
$load = $attr['load'];
$limit = $attr['limit'];
$order = $attr['order'];
/*
这里排序,读取条件什么的逻辑就不再细表,根据你自己的需求写
*/
//读取数据
$list = M("diycate")->where($w)->limit($limit)->order($order)->select();
//对数据简单处理
for($i=0;$i<count($list);$i++){
$array[$i] = $list[$i];
$array[$i][i] = $i+1;
$array[$i]['arcurl'] = U('News/slist','gid='.$list[$i]['gid']);
}
//读取标签
preg_match_all('/\[channel:(.*?)\]/',$content,$arry); //读取标签
$tag = $arry[0]; //匹配标签
$key = $arry[1]; //标签字段
$str='';
for($i=0;$i<count($array);$i++)
{
$c = $content; //读取模板内容
//替换标签
foreach($tag as $k=>$v){
//分割字符串,如果有函数那么执行函数后在输出
$arr = explode('|',$key[$k]);
$th = $array[$i][$arr[0]];
if($arr[1]){
$arr[1] = str_replace('###',$array[$i][$arr[0]],$arr[1]);
$a = '$th'." =$arr[1]";
eval($a.';');
}
$c = str_replace($v,$th,$c);
/*
重点来了,下面的函数指明了允许使用的标签,channel:为嵌套标签的关键字后面跟你之前定义标签名,第一个标签
里面的变量为上放标签最后得到的字符串,后面要继承沿用上级函数变量,才能使用多个标签。
*/
//嵌套标签
$r = TagLib_XML('channel:catelist',$c);
$r = TagLib_XML('channel:wdlist',$r);
}
$str.=$r;
}
return $str;
}
跟给标签配套的函数
//标签引擎
function TagLib_XML($tag,$content){
//检索标签
preg_match_all('/\<'.$tag.'(.*?)\>/',$content,$arry);
$tou = $arry[0];
$attr = $arry[1];
$fot = '</'.$tag.'>';
$tag = explode(':',$tag);
//声明可用嵌套标签 这里定义所有可以使用的标签,格式 '标签class类'=> '标签' 注意这里的标签不能加下划线'_'
$tagset = array(
'TagLibCate' => 'catelist,cateinfo',
'TagLibWd' => 'wdlist,wdinfo,wdpic,wdtjyd',
);
//检测该标签是否可用
$obj = array_search_str($tag[1],$tagset); //这是一个自定义数组函数 查询字符串是否在数组中存在
if(!$obj){ return $content; break;} //这里检测是否可用
//模板数据处理
$c = $content;
for($i=0; $i<count($tou);$i++){
/*找出要替换的标签例如
channel:catelist tid="[channel:gid]">
<a href="[tag:arcurl]">[tag:name]</a>
</channel:catelist>
*/
$str = strstr($content,$tou[$i]);
$str = str_replace($tou[$i],'',$str);
$str = strstr($str,$fot,true);
//执行替换操作
$run = '$ceshi = new '.$obj.';$runstr = $ceshi->_'.$tag[1].'($attr['.$i.'],$str);';
eval($run.';');
$strstr = $tou[$i].$str.$fot;
$c = str_replace($strstr,$runstr,$c);
}
return $c;
}
/*
* 查找数组中元素是否包含某个字符串,返回键
*/
function array_search_str($str,$arr){
foreach($arr as $k=>$v){
if(strstr($v,$str)){return $k;break;}
}
}
上面的代码有点功底的就可以看懂