Bookmark and Share

Lee's 程序人生

HTML CSS Javascript XML AJAX ATLAS C# C++ 数据结构 软件工程 设计模式 asp.net Java 数字图象处理 Sql 数据库
  博客园  :: 首页  :: 新随笔  :: 联系 :: 管理

对uchome模板引擎的解析

Posted on 2010-05-07 15:05  analyzer  阅读(765)  评论(0编辑  收藏  举报

转自:http://bbs.phpchina.com/redirect.php?tid=179467&goto=lastpost&sid=77eho6

 本人第一次在phpchina发表原创帖,如果写的不好,欢迎大家拍砖,下面进入正题!

一.模板语法
在模板里面,是可以直接显示php的变量的,也可以使用if,else,循环等,模板解析函数会将这些变量替换成实际的变量值。
1.设置变量的值
<!-–{eval $_TPL['titles'] = array(’日志’, ‘随便看看’);}–->
表示将$_TPL['titles']变量设置为array(’日志’, ‘随便看看’);

2.变量的显示
直接写变量的名字 $_GET[aa]

3.调用另外一个模板文件进来[模板里面再调用模板]
<!–-{template header}-–>实际上相当于php中的
相当于template(”header”) 即解析/template/default/header.htm文件
4.条件判断 <!–-{if xxx}-–>,<!–-{else}-–>,<!–-{/if}–->类
相当于php的if,else,但一定要<!–{/if}–>结束一个if语句
5.循环 <!–-{loop}–><!–-{/loop}-–>类
<!–-{loop $list $key $value}-–>
  
<!--{/loop}-->
相当于php的foreach($list $key=>$value)

6.在模板写php代码
    <!--{eval php代码;}-->
7.时间处理
    <!--{date('Y-m-d h:i',$time)}-->
8.头像处理
    <!--{avatar($uid, $size='small', $returnsrc = FALSE)}-->  returnsrc为true时返回头像的URL

当然了,以上模板语法可以嵌套,所以这也造成我们看模板文件的复杂性,比如在loop里面会有if,即表示每循环一次都要进行判断;又或者if里面有 loop,即表示只有满足条件了,才会进行循环!
二.模板解析过程
1.在php文件中引入模板
如果我们要在一个php文件中载入一个模板直接使用:
  include_once template("模板的名字");
如:我们要在index.php文件中引入首页的模板:
  include_once template("index");

2.模板的载入
上面步骤后php将调用template()函数
函数的原型为
01function template($name) {
02global $_SCONFIG$_SGLOBAL;
03if($_SGLOBAL['mobile']) {
04  $objfile = S_ROOT.'./api/mobile/tpl_'.$name.'.php';
05  if (!file_exists($objfile)) {
06   showmessage('m_function_is_disable_on_wap');
07  }
08else {
09  if(strexists($name,'/')) {
10   $tpl $name;
11  else {
12   $tpl "template/$_SCONFIG[template]/$name";
13  }
14  $objfile = S_ROOT.'./data/tpl_cache/'.str_replace('/','_',$tpl).'.php';
15  if(!file_exists($objfile)) {
16   include_once(S_ROOT.'./source/function_template.php');
17   parse_template($tpl);
18  }
19}
20return $objfile;
21}
其流程是先判断是不是wap访问,然后获得模板文件的路径,如果当前模板路径不存在则调用default目录下的同名模板,然后看模板文件缓存里是否存在,存在的话直接调用,否则引入source/function_template.php解析模板! 3.模板的解析 我们可以先看下source/function_template.php这个文件,我加了些注释,相信大家能够看懂
001  /*
002 [UCenter Home] (C) 2007-2008 Comsenz Inc.
003 $Id: function_template.php 12678 2009-07-15 03:21:21Z xupeng $
004*/
005if(!defined('IN_UCHOME')) {
006 exit('Access Denied');
007}
008$_SGLOBAL['i'] = 0;
009$_SGLOBAL['block_search'] = $_SGLOBAL['block_replace'] = array();
010function parse_template($tpl) {
011 global $_SGLOBAL$_SC$_SCONFIG;
012 //包含模板
013 $_SGLOBAL['sub_tpls'] = array($tpl);
014 //模板文件
015 $tplfile = S_ROOT.'./'.$tpl.'.htm';   
016 //模板缓存文件
017 $objfile = S_ROOT.'./data/tpl_cache/'.str_replace('/','_',$tpl).'.php';
018 //read
019 //如果模板文件不存在,则调用default下的同名模板
020 if(!file_exists($tplfile)) {
021  $tplfile str_replace('/'.$_SCONFIG['template'].'/''/default/'$tplfile);
022 }
023 //读取模板文件的内容    sreadfile()相当于file_get_contents()
024 $template = sreadfile($tplfile);
025 // 如果读取的内容为空则报错,模板文件不存在
026 if(empty($template)) {
027  exit("Template file : $tplfile Not found or have no access!");
028 }
029 //模板  替换<!–{template header}–>这类模板语法,然后使用readtemplate()函数获取其内容
030 $template = preg_replace("/\<\!\-\-\{template\s+([a-z0-9_\/]+)\}\-\-\>/ie","readtemplate('\\1')"$template);
031 //处理子<span href="tag.php?name=%D2%B3%C3%E6" onclick="tagshow(event)" class="t_tag">页面</span>中的代码
032 $template = preg_replace("/\<\!\-\-\{template\s+([a-z0-9_\/]+)\}\-\-\>/ie","readtemplate('\\1')"$template);
033 //解析模块调用
034 $template = preg_replace("/\<\!\-\-\{block\/(.+?)\}\-\-\>/ie""blocktags('\\1')",$template);
035 //解析广告   data/adtpl/ 下的广告页面
036 $template = preg_replace("/\<\!\-\-\{ad\/(.+?)\}\-\-\>/ie""adtags('\\1')"$template);
037 //时间处理  调用sgmdate()函数格式化时间
038 $template = preg_replace("/\<\!\-\-\{date\((.+?)\)\}\-\-\>/ie""datetags('\\1')",$template);
039 //头像处理  调用avatar()函数获取头像的url
040 $template = preg_replace("/\<\!\-\-\{avatar\((.+?)\)\}\-\-\>/ie""avatartags('\\1')",$template);
041 //<span href="tag.php?name=PHP" onclick="tagshow(event)" class="t_tag">PHP</span>代码  处理语法<!--{eval echo X_VER;}--> 标签里的php代码
042 $template = preg_replace("/\<\!\-\-\{eval\s+(.+?)\s*\}\-\-\>/ies""evaltags('\\1')",$template);
043 //开始处理
044 //变量 获取变量并对其',"进行转义
045 $var_regexp "(([url=]\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\[/url]])*)";
046 $template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s""{\\1}"$template);
047 $template = preg_replace("/([\n\r]+)\t+/s""[url=file://\\1]\\1[/url]"$template);
048 $template = preg_replace("/([url=]\\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff]+)\.([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)/s[/url]""[url=file://\\1[]\\1['\\2'[/url]]"$template);
049 $template = preg_replace("/\{([url=]\\\$[a-zA-Z0-9_\[\]\'\"\$\.\x7f-\xff]+)\}/s[/url]","<?=\\1?>"$template);
050 $template = preg_replace("/$var_regexp/es""addquote('<?=\\1?>')"$template);
051 $template = preg_replace("/\<\?\=\<\?\=$var_regexp\?\>\?\>/es""addquote('<?=\\1?>')",$template);
052 //逻辑  替换if,else
053 $template = preg_replace("/\{elseif\s+(.+?)\}/ies""stripvtags('<?php } elseif([url=file://\\1]\\1[/url]) { ?>','')"$template);
054 $template = preg_replace("/\{else\}/is""<?php } else { ?>"$template);
055 //循环  替换loop循环
056 for($i = 0; $i < 6; $i++) {
057  $template = preg_replace("/\{loop\s+(\S+)\s+(\S+)\}(.+?)\{\/loop\}/ies""stripvtags('<?php if(is_array([url=file://\\1]\\1[/url])) { foreach([url=file://\\1]\\1[/url] as [url=file://\\2]\\2[/url]) { ?>','\\3<?php } } ?>')"$template);
058  $template = preg_replace("/\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}(.+?)\{\/loop\}/ies","stripvtags('<?php if(is_array([url=file://\\1]\\1[/url])) { foreach([url=file://\\1]\\1[/url] as [url=file://\\2]\\2[/url] => [url=file://\\3]\\3[/url]) { ?>','\\4<?php } } ?>')"$template);
059  $template = preg_replace("/\{if\s+(.+?)\}(.+?)\{\/if\}/ies""stripvtags('<?php if([url=file://\\1]\\1[/url]) { ?>','\\2<?php } ?>')"$template);
060 }
061 //常量
062 $template = preg_replace("/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/s""<?=\\1?>",$template);
063  
064 //替换
065 if(!empty($_SGLOBAL['block_search'])) {
066  $template str_replace($_SGLOBAL['block_search'], $_SGLOBAL['block_replace'],$template);
067 }
068  
069 //换行
070 $template = preg_replace("/ \?\>[\n\r]*\<\? /s"" "$template);
071  
072 //附加处理
073 $template "<?php if(!defined('IN_UCHOME')) exit('Access Denied');?><?php subtplcheck('".implode('|', $_SGLOBAL['sub_tpls'])."''$_SGLOBAL[timestamp]''$tpl');?>$template<?php ob_out();?>";
074  
075 //write  写入模板缓存
076 if(!swritefile($objfile$template)) {
077  exit("File: $objfile can not be write!");
078 }
079}
080//转义函数
081function addquote($var) {
082 return str_replace("[url=]\\\[/url]"", "\"", preg_replace("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s""['\\1']"$var));
083}
084function striptagquotes($expr) {
085 $expr = preg_replace("/\<\?\=([url=]\\\$.+?)\?\>/s[/url]""[url=file://\\1]\\1[/url]",$expr);
086 $expr str_replace("[url=]\\\[/url]"", "\"", preg_replace("/\[\'([a-zA-Z0-9_\-\.\x7f-\xff]+)\'\]/s""[\\1]"$expr));
087 return $expr;
088}
089//处理变量
090function evaltags($php) {
091 global $_SGLOBAL;
092 $_SGLOBAL['i']++;
093 $search "<!--EVAL_TAG_{$_SGLOBAL['i']}-->";
094 $_SGLOBAL['block_search'][$_SGLOBAL['i']] = $search;
095 $_SGLOBAL['block_replace'][$_SGLOBAL['i']] = "<?php ".stripvtags($php)." ?>";
096  
097 return $search;
098}
099//处理模块调用
100function blocktags($parameter) {
101 global $_SGLOBAL;
102 $_SGLOBAL['i']++;
103 $search "<!--BLOCK_TAG_{$_SGLOBAL['i']}-->";
104 $_SGLOBAL['block_search'][$_SGLOBAL['i']] = $search;
105 $_SGLOBAL['block_replace'][$_SGLOBAL['i']] = "<?php block(\"$parameter\"); ?>";
106 return $search;
107}
108//处理广告调用
109function adtags($pagetype) {
110 global $_SGLOBAL;
111 $_SGLOBAL['i']++;
112 $search "<!--AD_TAG_{$_SGLOBAL['i']}-->";
113 $_SGLOBAL['block_search'][$_SGLOBAL['i']] = $search;
114 $_SGLOBAL['block_replace'][$_SGLOBAL['i']] = "<?php adshow('$pagetype'); ?>";
115 return $search;
116}
117//格式化时间
118function datetags($parameter) {
119 global $_SGLOBAL;
120 $_SGLOBAL['i']++;
121 $search "<!--DATE_TAG_{$_SGLOBAL['i']}-->";
122 $_SGLOBAL['block_search'][$_SGLOBAL['i']] = $search;
123 $_SGLOBAL['block_replace'][$_SGLOBAL['i']] = "<?php echo sgmdate($parameter); ?>";
124 return $search;
125}
126//头像处理
127function avatartags($parameter) {
128 global $_SGLOBAL;
129 $_SGLOBAL['i']++;
130 $search "<!--AVATAR_TAG_{$_SGLOBAL['i']}-->";
131 $_SGLOBAL['block_search'][$_SGLOBAL['i']] = $search;
132 $_SGLOBAL['block_replace'][$_SGLOBAL['i']] = "<?php echo avatar($parameter); ?>";
133 return $search;
134}
135function stripvtags($expr$statement='') {
136 $expr str_replace("[url=]\\\[/url]"", "\"", preg_replace("/\<\?\=([url=]\\\$.+?)\?\>/s[/url]""[url=file://\\1]\\1[/url]"$expr));
137 $statement str_replace("[url=]\\\[/url]"", "\""$statement);
138 return $expr.$statement;
139}
140//获取子模板的内容
141function readtemplate($name) {
142 global $_SGLOBAL$_SCONFIG;
143  
144 $tpl = strexists($name,'/')?$name:"template/$_SCONFIG[template]/$name";
145 $tplfile = S_ROOT.'./'.$tpl.'.htm';
146  
147 $_SGLOBAL['sub_tpls'][] = $tpl;
148  
149 if(!file_exists($tplfile)) {
150  $tplfile str_replace('/'.$_SCONFIG['template'].'/''/default/'$tplfile);
151 }
152 $content = sreadfile($tplfile);
153 return $content;
154}
155?>
解析完模板后在将其保存在模板缓存里供下次利用!
总结:我个人觉得uchome的模板引擎还是很简洁高效的,而且基本能满足模板的用法需要,实现美工和程序的分工!另外每次解析后以php文件的形式缓存起来,大大增加了其运行效率!
写这个帖子是因为我觉得这套模板引擎完全可以放到其他项目使用,希望对大家有帮助!
我要啦免费统计