通用模板机制

PHP通用的模板机制,流程一般是
1.初始化模板类
2.设置模板变量
3.分析模板中的的模板变量
4.输出内容

discuz模板机制

解析流程

discuz中的模板机制,将这一流程全都写在template()函数内的checktplrefresh(),编译生成缓存文件(如果模板缓存文件不存在,或者缓存文件的更改时间小于模板文件的更改时间),
1.初始化模板类,$template = new template();
2.解析模板变量(编译生成模板缓存文件),$template->parse_template($maintpl, $templateid, $tpldir, $file, $cachefile);
3.执行tempalte的php脚本中,直接 include template()返回的缓存文件,输出编译后内容。
下面是代码解析
template($tpl),调用模板文件,
checktplrefresh($tplfile, $tplfile, @filemtime(DISCUZ_ROOT.$cachefile), $templateid, $cachefile, $tpldir, $file);
filemtime(DISCUZ_ROOT.$cashefile)获取缓存文件(文件路径根据模板文件生成)的更改时间,
function checktplrefresh($maintpl, $subtpl, $timecompare, $templateid, $cachefile, $tpldir, $file) {
static $tplrefresh, $timestamp, $targettplname;
if($tplrefresh === null) {
$tplrefresh = getglobal('config/output/tplrefresh');
$timestamp = getglobal('timestamp');
}
//如果$timecompare为空(编译文件不存在),或者模板文件的更新时间(@filemtime(DISCUZ_ROOT.$subtpl))大于$timecompar
//都会执行模板缓存重新编译parse_template($maintpl, $templateid, $tpldir, $file, $cachefile)
 
if(empty($timecompare) || $tplrefresh == 1 || ($tplrefresh > 1 && !($timestamp % $tplrefresh))) {
if(empty($timecompare) || @filemtime(DISCUZ_ROOT.$subtpl) > $timecompare) {
require_once DISCUZ_ROOT.'/source/class/class_template.php';
$template = new template();
$template->parse_template($maintpl, $templateid, $tpldir, $file, $cachefile);
if($targettplname === null) {
$targettplname = getglobal('style/tplfile');
if(!empty($targettplname)) {
include_once libfile('function/block');
$targettplname = strtr($targettplname, ':', '_');
update_template_block($targettplname, getglobal('style/tpldirectory'), $template->blocks);
}
$targettplname = true;
}
return TRUE;
}
}
return FALSE;
}

下面解析parse_template();
function parse_template($tplfile, $templateid, $tpldir, $file, $cachefile) {
$basefile = basename(DISCUZ_ROOT.$tplfile, '.htm');
$file == 'common/header' && defined('CURMODULE') && CURMODULE && $file = 'common/header_'.CURMODULE;
$this->file = $file;
 
if($fp = @fopen(DISCUZ_ROOT.$tplfile, 'r')) {
$template = @fread($fp, filesize(DISCUZ_ROOT.$tplfile));
fclose($fp);
} elseif($fp = @fopen($filename = substr(DISCUZ_ROOT.$tplfile, 0, -4).'.php', 'r')) {
$template = $this->getphptemplate(@fread($fp, filesize($filename)));
fclose($fp);
} else {
$tpl = $tpldir.'/'.$file.'.htm';
$tplfile = $tplfile != $tpl ? $tpl.', '.$tplfile : $tplfile;
$this->error('template_notfound', $tplfile);
}
 
$var_regexp = "((\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\-\>)?[a-zA-Z0-9_\x7f-\xff]*)(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\])*)";
$const_regexp = "([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)";
 
$headerexists = preg_match("/{(sub)?template\s+[\w\/]+?header\}/", $template);
$this->subtemplates = array();
for($i = 1; $i <= 3; $i++) {
if(strexists($template, '{subtemplate')) {
$template = preg_replace("/[\n\r\t]*(\<\!\-\-)?\{subtemplate\s+([a-z0-9_:\/]+)\}(\-\-\>)?[\n\r\t]*/ies", "\$this->loadsubtemplate('\\2')", $template);
}
}
 
$template = preg_replace("/([\n\r]+)\t+/s", "\\1", $template);
$template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $template);
$template = preg_replace("/\{lang\s+(.+?)\}/ies", "\$this->languagevar('\\1')", $template);
$template = preg_replace("/[\n\r\t]*\{block\/(\d+?)\}[\n\r\t]*/ie", "\$this->blocktags('\\1')", $template);
$template = preg_replace("/[\n\r\t]*\{blockdata\/(\d+?)\}[\n\r\t]*/ie", "\$this->blockdatatags('\\1')", $template);
$template = preg_replace("/[\n\r\t]*\{ad\/(.+?)\}[\n\r\t]*/ie", "\$this->adtags('\\1')", $template);
$template = preg_replace("/[\n\r\t]*\{ad\s+([a-zA-Z0-9_\[\]]+)\/(.+?)\}[\n\r\t]*/ie", "\$this->adtags('\\2', '\\1')", $template);
$template = preg_replace("/[\n\r\t]*\{date\((.+?)\)\}[\n\r\t]*/ie", "\$this->datetags('\\1')", $template);
$template = preg_replace("/[\n\r\t]*\{avatar\((.+?)\)\}[\n\r\t]*/ie", "\$this->avatartags('\\1')", $template);
$template = preg_replace("/[\n\r\t]*\{eval\s+(.+?)\s*\}[\n\r\t]*/ies", "\$this->evaltags('\\1')", $template);
$template = preg_replace("/[\n\r\t]*\{csstemplate\}[\n\r\t]*/ies", "\$this->loadcsstemplate('\\1')", $template);
$template = str_replace("{LF}", "<?=\"\\n\"?>", $template);
$template = preg_replace("/\{(\\\$[a-zA-Z0-9_\-\>\[\]\'\"\$\.\x7f-\xff]+)\}/s", "<?=\\1?>", $template);
$template = preg_replace("/\{hook\/(\w+?)(\s+(.+?))?\}/ie", "\$this->hooktags('\\1', '\\3')", $template);
$template = preg_replace("/$var_regexp/es", "template::addquote('<?=\\1?>')", $template);
$template = preg_replace("/\<\?\=\<\?\=$var_regexp\?\>\?\>/es", "\$this->addquote('<?=\\1?>')", $template);
 
$headeradd = $headerexists ? "hookscriptoutput('$basefile');" : '';
if(!empty($this->subtemplates)) {
$headeradd .= "\n0\n";
foreach($this->subtemplates as $fname) {
$headeradd .= "|| checktplrefresh('$tplfile', '$fname', ".time().", '$templateid', '$cachefile', '$tpldir', '$file')\n";
}
$headeradd .= ';';
}
 
if(!empty($this->blocks)) {
$headeradd .= "\n";
$headeradd .= "block_get('".implode(',', $this->blocks)."');";
}
 
$template = "<? if(!defined('IN_DISCUZ')) exit('Access Denied'); {$headeradd}?>\n$template";
 
$template = preg_replace("/[\n\r\t]*\{template\s+([a-z0-9_:\/]+)\}[\n\r\t]*/ies", "\$this->stripvtags('<? include template(\'\\1\'); ?>')", $template);
$template = preg_replace("/[\n\r\t]*\{template\s+(.+?)\}[\n\r\t]*/ies", "\$this->stripvtags('<? include template(\'\\1\'); ?>')", $template);
$template = preg_replace("/[\n\r\t]*\{echo\s+(.+?)\}[\n\r\t]*/ies", "\$this->stripvtags('<? echo \\1; ?>')", $template);
 
$template = preg_replace("/([\n\r\t]*)\{if\s+(.+?)\}([\n\r\t]*)/ies", "\$this->stripvtags('\\1<? if(\\2) { ?>\\3')", $template);
$template = preg_replace("/([\n\r\t]*)\{elseif\s+(.+?)\}([\n\r\t]*)/ies", "\$this->stripvtags('\\1<? } elseif(\\2) { ?>\\3')", $template);
$template = preg_replace("/\{else\}/i", "<? } else { ?>", $template);
$template = preg_replace("/\{\/if\}/i", "<? } ?>", $template);
 
$template = preg_replace("/[\n\r\t]*\{loop\s+(\S+)\s+(\S+)\}[\n\r\t]*/ies", "\$this->stripvtags('<? if(is_array(\\1)) foreach(\\1 as \\2) { ?>')", $template);
$template = preg_replace("/[\n\r\t]*\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}[\n\r\t]*/ies", "\$this->stripvtags('<? if(is_array(\\1)) foreach(\\1 as \\2 => \\3) { ?>')", $template);
$template = preg_replace("/\{\/loop\}/i", "<? } ?>", $template);
 
$template = preg_replace("/\{$const_regexp\}/s", "<?=\\1?>", $template);
if(!empty($this->replacecode)) {
$template = str_replace($this->replacecode['search'], $this->replacecode['replace'], $template);
}
$template = preg_replace("/ \?\>[\n\r]*\<\? /s", " ", $template);
 
if(!@$fp = fopen(DISCUZ_ROOT.$cachefile, 'w')) {
$this->error('directory_notfound', dirname(DISCUZ_ROOT.$cachefile));
}
 
$template = preg_replace("/\"(http)?[\w\.\/:]+\?[^\"]+?&[^\"]+?\"/e", "\$this->transamp('\\0')", $template);
$template = preg_replace("/\<script[^\>]*?src=\"(.+?)\"(.*?)\>\s*\<\/script\>/ies", "\$this->stripscriptamp('\\1', '\\2')", $template);
$template = preg_replace("/[\n\r\t]*\{block\s+([a-zA-Z0-9_\[\]]+)\}(.+?)\{\/block\}/ies", "\$this->stripblock('\\1', '\\2')", $template);
$template = preg_replace("/\<\?(\s{1})/is", "<?php\\1", $template);
$template = preg_replace("/\<\?\=(.+?)\?\>/is", "<?php echo \\1;?>", $template);
 
flock($fp, 2);
fwrite($fp, $template);
fclose($fp);
}

解析重点

解析的重点主要是
变量输出 :{$var}
条件判断
<!--{if $var}-->
html
<!--{/if}-->

循环语句:
<!--{loop $arr $key $val}-->
HTML语句
<!--{/loop}-->

嵌套模板内容:
<!--{template common/header}-->
插件钩子:
<!--{hook/index_top}-->

discuz模板机制解析相关推荐

  1. discuz模板机制应用

    discuz用多了,觉得它的模板确实好用,便将它的数据库操作.模板提取出来,小组了一下,用于单独的开发用. 经过一个商城网站的开发,应用已经非常顺手了.商城主站完成后,进行代理网站的开发,其实主要就是 ...

  2. Discuz!NT 模板机制分析(转)

    作为产品中的一大特色,模板机制一经推出,就引来了大家特别是站长们的关注.但它所饱受的风风 雨雨也成了那时不少人关注的话题.而今天本人将结合在产品组中的开发经历,介绍一下模板机制在设计 使用时的一些体会 ...

  3. discuz模板解析注释

    <?php function parse_template($tplfile, $objfile) { global $options; //循环嵌套次数 $nest = 3; //打开模板文件 ...

  4. 快速理解shopex模板机制经验教程(一)

    shopex是程序和模板分离的,这样就大大方便了大家可以做出自己漂亮的外观网站, 虽然很多地方分离得不够,比如一些核心的业务流程区基本大家就很难修改了,但是大部分还是满足网站基本要求的. 首先,说说模 ...

  5. Tomcat根据JSP生成Servlet机制解析

    Tomcat根据JSP生成Servlet机制解析 JavaServer Pages(JSP) 简介 在传统的网页html文件中加入java程序片段和JSP标签,就构成了JSP网页:java程序片段可以 ...

  6. Shopex模板机制总览(摘要版)

    Shopex模板机制总览(摘要版) 此文档旨在为 shopex 二次开发提供一个便利的参考信息,借以打开 shopex 架构的大门,希望能带给读者一种登堂入室的感觉.由于 shopex 是半开放源代码 ...

  7. 【discuz】discuz模板语法

    Discuz! X 模板的解析主要是 ./source/class/class_template.php 文件解析处理的,如果需要深入了解请可以看看这个文件! 模板嵌套语法 将被嵌套模板内容解析为 P ...

  8. Discuz模板引擎标签

    界面风格与模板定制的详细说明 Discuz! 的模板采用文件保存,默认模板保存在 ./templates/default/ 目录中,该目录下 *.htm 文件是模板文件,*.lang.php 是语言包 ...

  9. 关于CMS的模板机制的一些讨论

    在讨论一个模板机制是否合理之前,首先要清楚它的使用群体,将模板与代码分别,最重要的作用在于实现项目标MVC机制,对于Java..Net等架构而言,最终展现层的模板都是用XML的语法设计的,使用类作为逻 ...

  10. 时序数据库连载系列: 时序数据库一哥InfluxDB之存储机制解析

    InfluxDB 的存储机制解析 本文介绍了InfluxDB对于时序数据的存储/索引的设计.由于InfluxDB的集群版已在0.12版就不再开源,因此如无特殊说明,本文的介绍对象都是指 InfluxD ...

最新文章

  1. MySQL外键与外键关系说明(简单易懂)
  2. 力扣:12正数转罗马数字(python) 简单粗暴解决方法
  3. CUDA编程之快速入门-----GPU加速原理和编程实现
  4. python中的def函数括号里的默认值_Python中的默认参数值
  5. oracle仅部分记录建立索引的方法
  6. linux命令(56):环境变量:/etc/profile、/etc/bashrc 、~/.profile、~/.bashrc
  7. android AVD 启动时报错
  8. Set集合之HashSet添加的数据是如何保证不重复的
  9. spss下载以及安装详细教程
  10. linux下玩三国志游戏,三国志威力无双手游官网版
  11. 百度小程序如何引流?给用户带来了更便捷、更人性化的体验
  12. 分享| 5个常见小程序营销线上玩法
  13. 童年汇老师教你如何给宝宝选玩具
  14. 笔记本控制台开启热点
  15. ATFX:5年期LPR利率大降15基点,USDCNH涨破年内高点
  16. 游戏建模需要报班学习吗?新手如何学习3D建模行业内容?
  17. 北京通信展的精华,都在这里!(上)
  18. 人工智能岗位替代----刑事警察
  19. Ubuntu16.04 使用apt-get命令安装Mesos
  20. 阡陌路-车行天下之汽车基础知识

热门文章

  1. 微信小程序 会议室课堂考勤签到助手 源码
  2. SPSS统计分析过程包括描述性统计、均值比较、一般线性模型、相关分析、回归分析、对数线性模型、聚类分析、数据简化、生存分析、时间序列分析、多重响应等几大类...
  3. 全国哀悼日,CSS如何把整个网页黑白显示
  4. 程序员为什么更容易脱发?
  5. 数学建模-线性规划模型基本原理与编程实现
  6. 路由器管理系统html代码,192.168.1.5 路由器登录管理界面操作步骤
  7. vs2005创建智能设备IE脚本错误
  8. 关于 Windows 不断报 脚本错误 当前页面的脚本发生错误 警告窗口的解决办法
  9. 基于8086的16位键盘操作系统仿真设计-基于8086LCD1602显示仿真设计-基于8086的LED中文显示屏显示设计-基于8086方波锯齿波三角波发生器-基于8086的LED点阵汉字流水显示设计
  10. 目标检测入门常见问题(深度学习 / 图像分类)