我是靠谱客的博主 碧蓝短靴,最近开发中收集的这篇文章主要介绍让你的thinkphp支持嵌套继承模板,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

最近想把后台重写一下,不想再用iframe了,用整页跳转的,当然想到的就是把之前那些固定的菜单做成一个模板,然后挖坑,内容页就填充到坑里


thinkphp里面有模板继承的功能 extend,可我发现它居然不支持嵌套继承


比如我写一个只加载bootstrap框架的basic页basic.html(放在Common/View/Boot/basic.html)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<!--<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />-->
		<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,minimum-scale =1,user-scalable=no" />
		<link rel="stylesheet" href="{$Think.PLUGIN_PATH}bootstrap/css/bootstrap.min.css" />
		<link rel="stylesheet" href="{$Think.CSS_PATH}lc.css" />	
		<block name="head"></block>
	</head>
	<body>
		<block name="body"></block>
		<script src="{$Think.PLUGIN_PATH}jquery/jquery-1.11.3.min.js"></script>
		<script src="{$Think.PLUGIN_PATH}bootstrap/js/bootstrap.min.js"></script>		
		<block name="foot"></block>		
	</body>
</html>

然后我再写一个我后台的admin_basic.html,继承刚才的basic页(放在Admin/View/Public/admin_basic.html),然后写导航、菜单,然后再挖坑。

<extend name="Common@Boot:basic" />
<block name="body">	
<div id="warpper">
	<nav>顶部的导航</nav>
        <!-- 这儿用tp的Widget扩展读取菜单 -->
        <div id="page_menu">{:W("Admin/getAction")}</div>
	<div id="page-warpper">
		<block name="body">内容页</block>
	</div>
</div>
</block>
<block name="foot">
	<block name="foot"></block>
</block>

然后我就写后台管理系统的首页 index.html

<extend name="Public:admin_basic" />
<block name="body">	
	这是我的后台系统管理
</block>
<block name="foot">
<script type="text/javascript">
	$(function(){
		alert("hello,world");
	});
</script>
</block>

tp它居然默认无法这样实现,我觉得这个功能应该是非常重要的呀,没办法,它不实现,只能我来实现了。

当然首先就是百度了,非常幸运,让我找到下面这个大湿的博客

http://blog.csdn.net/wangzuxi/article/details/44217355

具体是找到Thinkphp/Libray/Think/Template.class.php文件,在245行附近的parseExtend方法中 $content = $this->replaceBlock($content);这句后面增加 $content = $this->parseExtend($content); 让tp递归解析extend,然后再到340行附近的replaceBlock方法中,将  $content = $content[3]; 索引改为0。

请看下在代码,注释有[2develop]

protected function parseExtend($content) {
        $begin      =   $this->config['taglib_begin'];
        $end        =   $this->config['taglib_end'];        
        // 读取模板中的继承标签
        $find       =   preg_match('/'.$begin.'extends(.+?)s*?/'.$end.'/is',$content,$matches);
        if($find) {
            //替换extend标签
            $content    =   str_replace($matches[0],'',$content);
            // 记录页面中的block标签
            preg_replace_callback('/'.$begin.'blocksname=['"](.+?)['"]s*?'.$end.'(.*?)'.$begin.'/block'.$end.'/is', array($this, 'parseBlock'),$content);
            // 读取继承模板
            $array      =   $this->parseXmlAttrs($matches[1]);
            $content    =   $this->parseTemplateName($array['name']);
            $content    =   $this->parseInclude($content, false); //对继承模板中的include进行分析
            // 替换block标签
            $content = $this->replaceBlock($content);

            // [2DEVELOP] 支持多层继承
            $content = $this->parseExtend($content);
        }else{
            $content    =   preg_replace_callback('/'.$begin.'blocksname=['"](.+?)['"]s*?'.$end.'(.*?)'.$begin.'/block'.$end.'/is', function($match){return stripslashes($match[2]);}, $content);
        }
        return $content;
    }
  private function replaceBlock($content){
        
        static $parse = 0;
        $begin = $this->config['taglib_begin'];
        $end   = $this->config['taglib_end'];
        $reg   = '/('.$begin.'blocksname=['"](.+?)['"]s*?'.$end.')(.*?)'.$begin.'/block'.$end.'/is';      

        if(is_string($content)){
            do{
                $content = preg_replace_callback($reg, array($this, 'replaceBlock'), $content);
                
            } while ($parse && $parse--);

            return $content;
        } elseif(is_array($content)){
            if(preg_match('/'.$begin.'blocksname=['"](.+?)['"]s*?'.$end.'/is', $content[3])){ //存在嵌套,进一步解析
                $parse = 1;
                $content[3] = preg_replace_callback($reg, array($this, 'replaceBlock'), "{$content[3]}{$begin}/block{$end}");
                
                return $content[1] . $content[3];
            } else {
                $name    = $content[2];
                //[2DEVELOP] 支持多层继承,将下面原来的索引值3改为0
                $content = $content[0];
                $content = isset($this->block[$name]) ? $this->block[$name] : $content;
                return $content;
            }
        }
    }

我用它上面写的方法后,发现真的成功了,但是!可能我比较纠结,我发现了一个小问题。

我发现如果我basic里面的block的name名为body的话,我在admin_basic里如果也挖了一个坑name也为body的话,它就会覆盖admin_basic里我在body的block里写的内容了,要不就得避免block的name值一样。


我比较龟毛,一般主体我一直喜欢用body,所以我不能妥协!


让我研究了一上午,终于让我解决了


到Thinkphp/Libray/Think/Template.class.php

将345附近的$reg   = '/('.$begin.'blocksname=['"](.+?)['"]s*?'.$end.')(.*?)'.$begin.'/block'.$end.'/is';

改成下面这个

$reg   = '/('.$begin.'blocksname=['"]([^'"]+?)['"]s*?'.$end.')([^(?!'.$begin.'block)]*?)'.$begin.'/block'.$end.'/is';


</pre><pre name="code" class="php"> private function replaceBlock($content){
        
        static $parse = 0;
        $begin = $this->config['taglib_begin'];
        $end   = $this->config['taglib_end'];
        //$reg   = '/('.$begin.'blocksname=['"](.+?)['"]s*?'.$end.')(.*?)'.$begin.'/block'.$end.'/is';
        // [2DEVELOP]支持多层继承,上面是原来的正则
        $reg   = '/('.$begin.'blocksname=['"]([^'"]+?)['"]s*?'.$end.')([^(?!'.$begin.'block)]*?)'.$begin.'/block'.$end.'/is';

        if(is_string($content)){
            do{
                $content = preg_replace_callback($reg, array($this, 'replaceBlock'), $content);
                
            } while ($parse && $parse--);

            return $content;
        } elseif(is_array($content)){
            if(preg_match('/'.$begin.'blocksname=['"](.+?)['"]s*?'.$end.'/is', $content[3])){ //存在嵌套,进一步解析
                $parse = 1;
                $content[3] = preg_replace_callback($reg, array($this, 'replaceBlock'), "{$content[3]}{$begin}/block{$end}");
                
                return $content[1] . $content[3];
            } else {
                $name    = $content[2];

                $content = $content[3];
                $content = isset($this->block[$name]) ? $this->block[$name] : $content;
                return $content;
            }
        }
    }

我也不知这样改会不会有什么错误,不过我看了我其它页面都还没发现有错误的现象,仅供参考学习。


最后

以上就是碧蓝短靴为你收集整理的让你的thinkphp支持嵌套继承模板的全部内容,希望文章能够帮你解决让你的thinkphp支持嵌套继承模板所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(34)

评论列表共有 0 条评论

立即
投稿
返回
顶部