套模版的时候最烦的就是重复内容了,虽然ecshop cls_template.php支持{include file=”}, 但是有些时候还是麻烦了点, 所以就打算在此扩展一下 增加模版继承的支持。
下面是实现代码
这里只是简单实现了{extend}{block}标签 ,支持多重继承。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
/* * 把结果中的 block标签过滤掉,只要里面的内容 */ function trim_block($source){ return preg_replace('/{block name=[^}]*}(.*){\\/block}/Us', '\1', $source); } function extend_file($source){ global $files; $p="/{extends file='(.*)'}/"; $count=preg_match_all($p,$source,$out); if($count==0){ return $source; } #print_r($out); $filename=$out[1][0];//获取继承的模版路径路径 $p_contents=extend_file($files[$filename]); return extend_block($source,$p_contents); } /** * 继承模版内容 * @param $s_contents 子模板中的内容 * @param $p_contents 父模板中的内容 * return string 继承后的模版内容 */ function extend_block($s_contents,$p_contents){ $pblock=get_block($p_contents); $sblock=get_block($s_contents); foreach($pblock as $key=>$v){ if(isset($sblock[$key])){ $p_contents=str_replace($v['b'],$sblock[$key]['b'],$p_contents); } } return $p_contents; } /** * 提取模版中的block标签信息 返回一个数组 * @param $str 模版内容 * return array 返回格式如下(简化了表示一下为json格式): { "title" :{"val":"默认页面标题","b":"{block name='title'}默认页面标题{/block}"}, "head" :{"val":"head 内容","b" : "{block name='head'}head 内容{/block}"} } */ function get_block($str){ $pattern ="/{block name=['|\"](\w*)['|\"]}(.*){\\/block}/Us"; preg_match_all($pattern ,$str,$matches ,PREG_SET_ORDER); $l=array(); foreach($matches as $v){ $l[$v[1]]=array('val'=>$v[2],'b'=>$v[0]); } #print_r($l); return $l; } |
下面是测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
//此处为了简化代码将文件内容放到了数组中 $files['test1.html']=" <html> <head> <title>{block name='title'}默认页面标题{/block}</title> {block name='head'}{/block} </head> <body> {block name='body'}{/block} </body> </html> "; $files['test2.html']=" {extends file='test1.html'} {block name='head'} <!--子模版中的head覆盖了test1的title 但是也会被下面test3覆盖掉--> <link href=\"/css/style.css\" type=\"text/css\"/> {/block} "; $files['test3']=" {extends file='test2.html'} {block name='title'}我的页面标题 我把test1 中的title覆盖了{/block} {block name='head'} <link href=\"/css/style.css\" type=\"text/css\"/> <script src=\"/js/common.js\"></script> {/block} {block name=\"body\"}我的HTML页面内容在这里{/block} "; echo "result:\n"; print $out=extend_file($files['test3']); echo "最终结果:\n"; print trim_block($out); |
输出结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
result: <html> <head> <title>{block name='title'}我的页面标题 我把test1 中的title覆盖了{/block}</title> {block name='head'} <link href="/css/style.css" type="text/css"/> <script src="/js/common.js"></script> {/block} </head> <body> {block name="body"}我的HTML页面内容在这里{/block} </body> </html> 最终结果: <html> <head> <title>我的页面标题 我把test1 中的title覆盖了</title> <link href="/css/style.css" type="text/css"/> <script src="/js/common.js"></script> </head> <body> 我的HTML页面内容在这里 </body> </html> |
参考