您现在的位置是:首页 > cms教程 > phpcms教程phpcms教程
phpcms模板引擎源码分析
恨松2025-05-25 14:12:20phpcms教程已有2人查阅
导读2 函数 template函数是在global.func.php 里面定义的。 在前面的phpcms 的首页 index.php 里就见到了。3 用法: include template()用法很熟, 呵呵其实和 dz 的模板引擎一样的用法。
模板引擎实现的分析:
1 /*
2 函数 template函数是在global.func.php 里面定义的。 在前面的phpcms 的首页 index.php 里就见到了。
3 用法: include template()用法很熟, 呵呵其实和 dz 的模板引擎一样的用法。
4 但DZ的模板引擎比 PHPCMS 的简单很多,因为没有用到模板的标签技术。 大家有空可以研究下DZ的模板引擎。
5 这里不说。好分析下下面这个 模板的主要函数吧。他的作用是返回编译好的模板文件路径。
6 也就是把模板 X.html(模板文件) 用正则替换成 x.php(编译后的PHP文件).然后使用 include函数。
7 懂了吧! php的模板引擎都一个鸟样。 然后剩下的就是正则的东西了。等下再说。
8 */
9 function template($module = 'phpcms', $template = 'index')
10 {
11 global $CONFIG;
12
13 /*
14因为phpcms是分模块来存放模板文件。所以 template 函数有两个参数:
15第一个就是模块目录名,第二个就是此模块里面的模板文件名.
16$CONFIG['templatescachedir']这个是放编译后php文件存放的目录。
17在config.inc.php 站点配置文件里面定义的自己去看。 这样就取得了模板编译后的php文件路径。
18 */
19 $compiledtplfile = $CONFIG['templatescachedir'].$module.'_'.$template.'.tpl.php';
20
21 // $CONFIG['templaterefresh']在 config.inc.php里面配置了。
22 // 默认是1。是更新模板开关。如果你设置为0 那么模板更新了。程序也不会更新。
23 if($CONFIG['templaterefresh'])
24 {
25 /*
26和下面那句意思差不多。$CONFIG['defaulttemplate'] 是默认模板目录。
27这句是获取你要的那个模块和里面的那个模板文件的路径(@@获取没编译前的模板文件)
28 */
29 $tplfile = PHPCMS_ROOT.'/templates/'.$CONFIG['defaulttemplate'].'/'.$module.'/'.$template.'.html';
30
31 /*
32我把文件编译成了php文件。那么模板改变了。 php文件总得也改变吧。
33 要不你修改了模板后。站还是以前那个样子没变那有什么意思呢。
34 首先判断模板编译文件是否存在。如果不存在那么后边那个条件不用判断了。
35 因为编译文件都不存在。程序肯定运行不了拉。(
36 因为其实我们主要是运行编译后的那个php文件,模板文件是html的运行个P呀)
37 或后边那个 @filemtime($tplfile) > @filemtime($compiledtplfile)
38 很容易就明白:函数 filetime() 判断文件最近修改的时间,返回Unix 时间戳。
39 如果模板文件的修改时间 大于 编译文件。 那么证明 模板文件在 编译文件生成后 还进行了修改。
40 那么我们是不是还要在更新次编译文件呀 ,那是肯定的拉。 所以继续执行下去。
41 */
42 if(!file_exists($compiledtplfile) || @filemtime($tplfile) > @filemtime($compiledtplfile))
43 {
44 // 加载编译函数
45require_once PHPCMS_ROOT.'/include/template.func.php';
46
47// 这个就是模板的 编译启动函数 ,带动一系列的模板编译函数来最终生成模板编译文件。
48template_refresh($tplfile, $compiledtplfile);
49 }
50 }
51
52 // 返回 模板编译后的PHP文件路径。
53 return $compiledtplfile;
54 }
55
56 defined('IN_PHPCMS') or exit('Access Denied');
57
58 // 和上面那个一样是编译模板启动函数。不过两函数的参数不一样,按照上下文意思。
59 // 这个函数是为了配合批量编译模板而写的。第一个是模块目录名,第二是模板文件名,解释同下。请看下面那个
60 function template_compile($module,$template)
61 {
62 global $CONFIG;
63
64 $content = file_get_contents(PHPCMS_ROOT.'/templates/'
65. $CONFIG['defaulttemplate'].'/'.$module.'/'.$template.'.html');
66
67 $content = template_parse($content);
68
69 $compiledtplfile = $CONFIG['templatescachedir'].$module.'_'.$template.'.tpl.php';
70
71 $strlen = file_put_contents($compiledtplfile, $content);
72
73 @chmod($compiledtplfile, 0777);
74
75 return $strlen;
76 }
77
78 // 模板编译启动函数。 参数 第一个是 模板文件名第二个是 编译后的php文件名
79 function template_refresh($tplfile,$compiledtplfile)
80 {
81 // 使用了php5 的最爽函数:file_get_contents() 获取文件的内容 。
82 $str = file_get_contents($tplfile);
83
84 /*
85* 然后 使用 template_parse() 函数来对文件内容进行替换。
86* 比如把一些我们自己定义的语句:{if xx > xx}
87* 正则替换成 <?php if(xx > xx){?>具体看下面
88*/
89 $str = template_parse($str);
90
91 // 编译完成后。把内容写到我们的 那个所谓的编译PHP文件。
92 $strlen = file_put_contents($compiledtplfile, $str);
93
94 // 别忘了设置下权限。
95 @chmod($compiledtplfile, 0777);
96
97 //返回 写到编译文件里的内容字大小节数,下面我们会看下 template_parse() 函数
98 return $strlen;
99 }
100
101 // 这个很有用。批量编译某模块目录下的模板文件
102 function template_module($module)
103 {
104 global $CONFIG;
105
106 /*
107glob 函数取得 在此路径下的所有 *.html 以html为扩展名的文件列表。 具体看手册。
108*/
109 $files = glob(PHPCMS_ROOT.'/templates/'.$CONFIG['defaulttemplate'].'/'.$module.'/*.html');
110
111 if(is_array($files))
112 {
113 foreach($files as $tpl)
114 {
115 //开始批量
116$template = str_replace('.html', '', basename($tpl));
117
118// 获取模板文件名。以次来做编译后的PHP文件名
119template_compile($module, $template);
120 }
121 }
122
123 return TRUE;
124 }
125
126 // 这个是比下面那个更大批量的生成。因为 $MODULE 里面的所有模块
127 // $MODULE 存在于缓存文件模板。前面已经说了。自己看吧
128 function template_cache()
129 {
130 global $MODULE;
131
132 foreach($MODULE as $module=>$m)
133 {
134 template_module($module);
135 }
136
137 return TRUE;
138 }
139
140 /*
141 哇,别给它吓到。其实都是些简单的正则。只要知道他们是干什么的就好办了。 在模板里面我们使用了些自己定义的标签呀。
142 语句呀。这些东西不是PHP标准语法。所以根本不可能运行。
143 那么怎么办呢。通过正则对我们自己定义的语法 。转变成标准的PHP语法。
144 然后写到我们的 PHP文件里。所以下面正则都是对我们自己定义的语法进行编译。
145 下面讲解下正则。按照本人水平解释。大概的解释了下。不过不懂正则的请自己百度学下。
146 有不对的地方。大家可以讨论下。@@ 还没懂 preg_replace() 函数的同学兄弟朋友姐妹。请自己看手册。
147 */
148 function template_parse($str)
149 {
150 // 用 \n\r 过滤掉 tab制表符,[url=file://\\1]\\1[\url] 是逆向引用了第一个括号里面\n换行\r换页匹配的文本
151 //(@@解释好要口,较好自己看下正则知识 /s为修正符。自己百度吧)
152 $str = preg_replace("/([\n\r]+)\t+/s", "[url=file://\\1]\\1", $str[\url]);
153
154 // 以 {xx} 来替换 <!--{xx}--> {xx}在下面肯定还要进行第二次正则替换,要不是不能在PHP里面运行的。
155 // .+? 和 .+ 一个是懒惰 一个是贪婪。看名字就知道。不知道的 百度吧: 正则贪婪。
156 $str = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}",$str);
157
158 /*
159* 把模板里面的 {template 'xx','jj'} 编译成PHP标准写法:<?php include template('xx','jj') ?>
160* 大家可能一看就明白了: include template()这个在那里见过。对了。这个在PHP里也可以运行的。因为 template() 函数不是定义了吗。
161*/
162 $str = preg_replace("/\{template\s+(.+)\}/","\n<?php include template([url=file://\\1]\\1[\url]); ?>\n",$str);
163
164 /* 模板里面的 {include xx.php} 编译成 PHP文件里的 <?php include xx.php?>**/
165 $str = preg_replace("/\{include\s+(.+)\}/","\n<?php include [url=file://\\1]\\1[\url]; ?>\n",$str);
166
167 /* 模板里面的 {php xxxx} 编译成 <?php xxxx?>大家也应该明白了。 xxxx 肯定是PHP的标准语法拉。
168* 所以phpcms模板语句: {php } 就是用来给你在模板里写要运行的PHP语句。在smarty 里也有这功能**
169*/
170 $str = preg_replace("/\{php\s+(.+)\}/","\n<?php [url=file://\\1?]\\1?>\n",$str[\url]);
171
172 /* 这个就更简单了。 把模板里面的{if xxxx}编译成 <?php if(){?>
173* 看这样一步一步的把一些自己定义的语句编译成PHP的标准语法。这个就叫模板引擎了。**
174*/
175 $str = preg_replace("/\{if\s+(.+?)\}/","<?php if([url=file://\\1]\\1[\url]) { ?>",$str);
176
177 /* {else } 转 <?php } else {?>**/
178 $str = preg_replace("/\{else\}/","<?php } else { ?>",$str);
179
180 /* {elseif } 转 <?php } elseif {?>**/
181 $str = preg_replace("/\{elseif\s+(.+?)\}/","<?php } elseif ([url=file://\\1]\\1[\url]) { ?>",$str);
182
183 /* {/if} 转 <?php }?>phpcms 模板语法有: {/if}的哦。大家别忘了,要不 php肯定运行不了**/
184 $str = preg_replace("/\{\/if\}/","<?php } ?>",$str);
185
186 /* 下面就是循环了。模板里用{loop xx jj} 其实编译成了PHP的 foreach(xx AS jj) 这样大家都会用了吧**/
187 $str = preg_replace("/\{loop\s+(\S+)\s+(\S+)\}/",
188 "<?php if(is_array([url=file://\\1]\\1[\url]))
189 foreach([url=file://\\1]\\1[\url] AS [url=file://\\2]\\2[\url]) { ?>",$str);
190
191 /* 这句和上面也差不多。不过是多了个取出数组的标名{loop xx jj yy}成 foreach(xx as jj=> yy)**/
192 $str = preg_replace("/\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}/",
193 "\n<?php if(is_array([url=file://\\1]\\1[\url]))
194 foreach([url=file://\\1]\\1[\url] AS [url=file://\\2]\\2[\url] => [url=file://\\3]\\3[\url]) { ?>",$str);
195
196
197 /* 循环结束别忘了 {/loop}对应PHP的 <?php }?>**/
198 $str = preg_replace("/\{\/loop\}/","\n<?php } ?>\n",$str);
199
200 /* {tag_xx}替换为 get_tag('xx')get_tag()函数是自己定义的函数,
201* 因为phpcms 的模板引擎应用了标签功能。这个函数就是为了调用标签的。**
202*/
203 $str = preg_replace("/\{tag_([^}]+)\}/e", "get_tag('\\1')", $str);
204
205 /* {xxx(jj)}这么个奇怪的东西。因为奇怪所以我找了下PHPCMS的模板文件。
206* 找了几个文件都没发现这个怪物。大家有谁找到的说下我去看下。怕是我理解错了正则。先谢了**
207*/
208 $str = preg_replace("/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\(([^{}]*)\))\}/",
209 "<?php echo [url=file://\\1;?]\\1;?>",$str[\url]);
210
211
212 /* {$xxx(wwsd)} 专换成 <?php echo xxx(wwsd)?> 当然了 xxx() 是程序中定义过的函数**/
213 $str = preg_replace("/\{\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\(([^{}]*)\))\}/",
214 "<?php echo [url=file://\\1;?]\\1;?>",$str[\url]);
215
216 /* 把{$xxjj} 转成 <?php echo $xxjj?>当然了是把变量输出**/
217 $str = preg_replace("/\{([url=file://\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/]\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/",
218 "<?php[\url] echo [url=file://\\1;?]\\1;?>",$str[\url]);
219
220 /* 主要是把{$xxx['jj']} 转成 <?php echo $xxx['jj']?>
221* addquote() 函数自己定义的看下面,二次过滤。有代验证,头昏了看太久的黄颜色字。我昏**
222*/
223 $str = preg_replace("/\{([url=file://\\$[a-zA-Z0-9_\[\]\]\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff]+)\}/es[\url]",
224 "addquote('<?php echo [url=file://\\1;?]\\1;?>')",$str[\url]);
225
226 /* {XXJJ}<?php echo XXJJ?>XXJJ 是我们定义的常量**/
227 $str = preg_replace("/\{([A-Z_\x7f-\xff][A-Z0-9_\x7f-\xff]*)\}/s",
228 "<?php echo [url=file://\\1;?]\\1;?>",$str[\url]);
229
230 /* 之后别忘了在自己的每个编译后的文件里加上这个。以前讲过了不明白找前面例子**/
231 $str = "<?php defined('IN_PHPCMS') or exit('Access Denied'); ?>".$str;
232
233 // 之后返回过滤完成的内容
234 return $str;
235 }
236
237 // 这个函数在下面这个编译函数里面看到了。 其实就是获取对应标签的内容,头有点昏,下节再说标签吧。
238 function get_tag($tagname)
239 {
240 global $tags, $html, $CONFIG;
241
242 if(!$tags) {
243 require PHPCMS_ROOT.'/templates/'.$CONFIG['defaulttemplate'].'/tags.php';
244 }
245
246 if(!$html) {
247 require PHPCMS_ROOT.'/templates/'.$CONFIG['defaulttemplate'].'/html.php';
248 }
249
250 if(!isset($tags[$tagname])) {
251 return '{tag_'.$tagname.'}';
252 }
253
254 $code = isset($html[$tagname])
255 ? 'tag_read('.$html[$tagname].')'
256 : $tags[$tagname];
257
258 return "<?php echo $code;?>";
259 }
260
261 function addquote($var)
262 {
263 return str_replace("[url=]\\\[\url]\"", "\"", preg_replace("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s", "['\\1']", $var));
264 }
265 /*
266 [/php]
267
268
269 下一节讲phpcms 的模板标签功能,讲得不好.大侠就别笑我了
本文标签:
声明:本文由代码号注册/游客用户【恨松】供稿发布,本站不对用户发布的phpcms模板引擎源码分析信息内容原创度和真实性等负责。如内容侵犯您的版权或其他权益,请留言并加以说明。站长审查之后若情况属实会及时为您删除。同时遵循 CC 4.0 BY-SA 版权协议,尊重和保护作者的劳动成果,转载请标明出处链接和本声明内容。本文作者:恨松» https://www.ebingou.cn/dmh/15616.html
很赞哦! (0)
暂无内容 |
暂无内容 |
相关文章
暂无内容 |
暂无内容 |
随机图文
phpcms如何更换模板的步骤方法
1、上传模版文件到服务器;2、在站点管理里边【模板风格配置】选择新模板;3、设置不同模型对应模板;4、修改现有的栏目,匹配新模板;5、更新栏目缓存、系统缓存,更新HTML静态页。phpcms首页加上用户登录的信息方法代码示例
我用的是cookie的方法,请先打开discuz的文件找到函数function setloginstatus()把以下的代码在首页我们可以这里做:注意这里的cookiephpcms不支持fsockopen函数的解决方法
phpcms不支持fsockopen函数怎么办?安装phpcms v9时空间不支持fsockopen函数的办法由于最近多种cms程序爆出各种各样的漏洞,其中由于fsockopen引起的漏洞入侵尤其的多phpcms关联文章排序不变的解决方法
phpcms关联文章排序不变问题的修改方法:打开 phpcms/modules/content/classes/content_tag.class.php 内容模型标签类,发现该标签仅在内容存在人为设置的相关阅读时
留言与评论 (共有 0 条评论) |