discuz模板机制解析

    xiaoxiao2026-04-25  13

    通用模板机制

    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}-->
    转载请注明原文地址: https://ju.6miu.com/read-1309223.html
    最新回复(0)