thinkphp实战4 自定以标签 tag 结合youdian cms 标签系统

拿youdiancms的channellist 来举例

                <navigationlist id="n" channelid='$T4'>
                    <a class="a{$i}" href="{$n.ChannelUrl}" target="{$n.ChannelTarget}">
                        <li>
                            <div class="ChannelIcon"><img src="{$n.ChannelIcon}" title="{$n.ChannelName}" alt="{$n.ChannelName}" /></div>
                            <div class="ChannelName">{$n.ChannelName}</div>
                        </li>
                    </a>
                </navigationlist>

参看thinkphp3.0的第13章

13.5.4          标签库驱动

系统的标签库驱动扩展目录位于Extend/Driver/TagLib目录下面,命名规范是:

TagLib+标签库名称(首字母大写)

目前已经提供了Html标签库驱动支持,标签库驱动扩展必须继承TagLib类,例如我们扩展一个Test标签库:

Class TagLibTest extends TagLib{}

首先需要定义标签库的标签定义,标签定义包含了所有标签库中支持的所有标签,定义方式如下:

protected $tags   =  array(

  // 定义标签

'input'=>array('attr'=>'type,name,id,value','close'=>0), // input标签

);

在 App\Core\Extend\Driver\TagLib 里面有个

TagLibYouDian.class.php

那么这个标签库的名字就是YouDian

protected $tags=array(

'navigationlist'   => array('attr'=>'id,channelid,channelmodelid,offset,length,key,mod,depth,empty,idlist,showhidden,field', 'level'=>4, 'alias'=>'channellist')

);

定义了一个自定义的标签 navigationlist 有很多属性 'attr'=>'id,channelid,channelmodelid,offset,length,key,mod,depth,empty,idlist,showhidden,field'

'level'=>4 嵌套级别

'alias'=>'channellist' 别名

现在要定义解析这个navigationlist的方法 标签的方法前面要加上 _

public function _navigationlist($attr, $content){
        //首先通过parseXmlAttr来解析navigationlist得到tags所有属性
		$tag        = $this->parseXmlAttr($attr,'navigationlist');		
		$channelid  = !empty($tag['channelid']) ? $tag['channelid'] : 0;
		$channelmodelid  = ( isset($tag['channelmodelid']) && is_numeric($tag['channelmodelid']) ) ? $tag['channelmodelid'] : -1;
		
		$idlist  = !empty($tag['idlist']) ? trim($tag['idlist']) : -1;

		$id        = $tag['id'];
		$empty  = isset($tag['empty'])?$tag['empty']:'';
		$key     =   !empty($tag['key'])?$tag['key']:'i';
		$mod    =   isset($tag['mod'])?$tag['mod']:'2';
		$depth    =   isset($tag['depth']) ? $tag['depth'] : '1';
	
		$offset     =   ( isset($tag['offset']) && is_numeric($tag['offset']) ) ? "offset='".$tag['offset']."'" : '';
		$length    =   isset($tag['length']) ? "length='".$tag['length']."'" : '';
		
		$showhidden  = isset($tag['showhidden']) ? trim($tag['showhidden']) : 0; //默认不显示隐藏频道
		$isshow = ($showhidden == 0) ? 1 : -1;
		$field     =   !empty($tag['field']) ? trim($tag['field']) : '';
		
		if('$' == substr($channelid, 0, 1)) {
			$channelid  =  $this->autoBuildVar(substr($channelid,1));
		}
		if('$' == substr($channelmodelid, 0, 1)) {
			$channelmodelid  =  $this->autoBuildVar(substr($channelmodelid,1));
		}
		
		if('$' == substr($idlist, 0, 1)) {
			$idlist  =  $this->autoBuildVar(substr($idlist,1));
		}
		
		$parseStr = "<volist name=':get_navigation($channelid,$depth,\"$idlist\",$isshow,$channelmodelid,-1,\"$field\")' id='$id'  empty=\"$empty\"  key='$key'  mod='$mod'  $offset  $length>$content</volist>";
		
		return $parseStr;
	}

('50','TAGLIB_PRE_LOAD','YouDian',NULL,'config','1','0')

在ThinkTemplate.class.php中的parse函数会处理 TAGLIB_PRE_LOAD

 // 预先加载的标签库 无需在每个模板中使用taglib标签加载 但必须使用标签库XML前缀
        if(C('TAGLIB_PRE_LOAD')) {
            $tagLibs =  explode(',',C('TAGLIB_PRE_LOAD'));
            foreach ($tagLibs as $tag){
                $this->parseTagLib($tag,$content);
            }
        }

模板中就可以使用 TagLibYouDian。不用再开头使用<taglib name='YouDian' />去申请了

就是说比如input 如果是需要解析为test的空间,那么就需要 <test:input 这样的标记

ThinkTemplate.class.php 解析模板 content 

通过fetch函数取得文件

    public function fetch($templateFile,$templateVar) {
        $this->tVar = $templateVar;
        $templateCacheFile  =  $this->loadTemplate($templateFile);
        // 模板阵列变量分解成为独立变量
        extract($templateVar, EXTR_OVERWRITE);
        //载入模版缓存文件
        include $templateCacheFile;
    }

继续进入loadTemplate继续进入compiler进入parse 后优先先解析 TAGLIB_LOAD 再解析 TAGLIB_PRE_LOAD 这里就解析navigationlist   这里调用了TagLibYouDian.class.php 的_navigationlist函数

$parseStr = "<volist name=':get_navigation($channelid,$depth,\"$idlist\",$isshow,$channelmodelid,-1,\"$field\")' id='$id'  empty=\"$empty\"  key='$key'  mod='$mod'  $offset  $length>$content</volist>";

解析出来以后 还不是已经处理好的纯html语言。而是带有内置volist的模板

接下来继续解析TAGLIB_BUILD_IN

// 内置标签库 无需使用taglib标签导入就可以使用 并且不需使用标签库XML前缀
        $tagLibs =  explode(',',C('TAGLIB_BUILD_IN'));
        foreach ($tagLibs as $tag){
            $this->parseTagLib($tag,$content,true);
        }

最后解析tagName

//解析普通模板标签 {tagName}
$content = preg_replace('/('.$this->config['tmpl_begin'].')(\S.+?)('.$this->config['tmpl_end'].')/eis',"\$this->parseTag('\\2')",$content);

就是说是按次序来的。前面的解析可以返回 能让后面解析的标签语句。

_navigationlist里面的content就是 标签内部的内容

<a class="a{$i}" href="{$n.ChannelUrl}" target="{$n.ChannelTarget}">
                        <li>
                            <div class="ChannelIcon"><img src="{$n.ChannelIcon}" title="{$n.ChannelName}" alt="{$n.ChannelName}" /></div>
                            <div class="ChannelName">{$n.ChannelName}</div>
               </li>
</a>

前面通过youdian的解析 navigationlist 变成了

volist name=":get_navigation(xxx xxx xxx)"这里就是通过 函数获取数据集

<volist name=':get_navigation($T4,1,"-1",1,-1,-1,"")' id='n' empty="" key='i' mod='2'>
    <a class="a{$i}" href="{$n.ChannelUrl}" target="{$n.ChannelTarget}">
        <li>
            <div class="ChannelIcon">
                <img src="{$n.ChannelIcon}" title="{$n.ChannelName}" alt="{$n.ChannelName}" />
            </div>
            <div class="ChannelName">{$n.ChannelName}</div>
        </li>
    </a>
</volist>

又变成了TP自己的的volist标签

name和id必选 name是模板变量, 一般是二维数组 id是循环变量  key是当前的key变量从1开始递增

进入volist的content是

<a class="a{$i}" href="{$n.ChannelUrl}" target="{$n.ChannelTarget}">
    <li>
        <div class="ChannelIcon"><img src="{$n.ChannelIcon}" title="{$n.ChannelName}" alt="{$n.ChannelName}" /></div>
        <div class="ChannelName">{$n.ChannelName}</div>
    </li>
</a>

解析以后是

<?php 
	$_result=get_navigation($T4,1,"-1",1,-1,-1,"");
	if(is_array($_result)): 
		$i = 0; 
		$__LIST__ = $_result;
		if( count($__LIST__)==0 ) : 
			echo "" ;
		else: 
			foreach($__LIST__ as $key=>$n): 
				$mod = ($i % 2 );++$i;
?>
<a class="a<?php echo ($i); ?>" href="<?php echo ($n[" ChannelUrl"]); ?>" target="
    <?php echo ($n["ChannelTarget"]); ?>">
    <li>
        <div class="ChannelIcon"><img src="<?php echo ($n[" ChannelIcon"]); ?>" title="
            <?php echo ($n["ChannelName"]); ?>" alt="
            <?php echo ($n["ChannelName"]); ?>" /></div>
        <div class="ChannelName">
            <?php echo ($n["ChannelName"]); ?>
        </div>
    </li>
</a>
<?php 
	endforeach; 
	endif; 
	else: 
	echo "" ;
	endif; 
?>

经过整理以后是下面的样子


	$_result=get_navigation($T4,1,"-1",1,-1,-1,"");
	if(is_array($_result))
	{
		$i = 0; 
		$__LIST__ = $_result;
		if( count($__LIST__)==0 )
		 {
			echo "" ;
		}
		else
		{
			foreach($__LIST__ as $key=>$n)
			{
				$mod = ($i % 2 );++$i;
				/*content部分开始*/
				<a class="a<?php echo ($i); ?>" href="<?php echo ($n[" ChannelUrl"]); ?>" target="
				<?php echo ($n["ChannelTarget"]); ?>">
				<li>
				    <div class="ChannelIcon"><img src="<?php echo ($n[" ChannelIcon"]); ?>" title="
				        <?php echo ($n["ChannelName"]); ?>" alt="
				        <?php echo ($n["ChannelName"]); ?>" />
				    </div>
				    <div class="ChannelName">
				        <?php echo ($n["ChannelName"]); ?>
				    </div>
				</li>
				</a>
				/*content部分结束*/
			}
				
		}
	else{
		echo "" ;
	} 

 

youdian所有的channel都再youdian_channel数据库内 

通过get_navigation取得了 ParentID为23的所有子id 然后输出了样式

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值