剥离DISCUZ X系列的模板引擎机制
首先定义几个常量define('DISCUZ_ROOT',dirname(__FILE__));
define('IN_DISCUZ',true);
define('STYLEID',1);
define('TEMPLATEID',1);
define('TPLDIR','templates/default');
这些常量是必须要定义的。
其次把需要的函数分出来。
function strexists($string, $find) {
return !(strpos($string, $find) === FALSE);
}
function template($file, $templateid = 0, $tpldir = '', $gettplfile = 0, $primaltpl='') {
$tpldir = $tpldir ? $tpldir : (defined('TPLDIR') ? TPLDIR : '');
$tpldir = './'.$tpldir;
$templateid = $templateid ? $templateid : (defined('TEMPLATEID') ? TEMPLATEID : '');
$tplfile = ($tpldir ? $tpldir.'/' : './template/').$file.'.htm';
$filebak = $file;
$file == 'common/header' && defined('CURMODULE') && CURMODULE && $file = 'common/header_'.$_G['basescript'].'_'.CURMODULE;
$cachefile = './data/template/'.(defined('STYLEID') ? STYLEID.'_' : '_').$templateid.'_'.str_replace('/', '_', $file).'.tpl.php';
if($templateid != 1 && !file_exists(DISCUZ_ROOT.$tplfile)) {
$tplfile = './template/default/'.$filebak.'.htm';
}
if($gettplfile) {
return $tplfile;
}
checktplrefresh($tplfile, $tplfile, @filemtime(DISCUZ_ROOT.$cachefile), $templateid, $cachefile, $tpldir, $file);
return DISCUZ_ROOT.$cachefile;
}
function checktplrefresh($maintpl, $subtpl, $timecompare, $templateid, $cachefile, $tpldir, $file) {
static $tplrefresh, $timestamp, $targettplname;
if(empty($timecompare) || $tplrefresh == 1 || ($tplrefresh > 1 && !($timestamp % $tplrefresh))) {
if(empty($timecompare) || @filemtime(DISCUZ_ROOT.$subtpl) > $timecompare) {
require_once DISCUZ_ROOT.'./class_template.php';
$template = new template();
$template->parse_template($maintpl, $templateid, $tpldir, $file, $cachefile);
return TRUE;
}
}
return FALSE;
}
其中解析使用的函数为function template;
在此,修改template类
<?php
/**
* [Discuz!] (C)2001-2099 Comsenz Inc.
* This is NOT a freeware, use is subject to license terms
*
* $Id: class_template.php 21214 2011-03-18 09:25:12Z monkey $
*/
if(!defined('IN_DISCUZ')) {
exit('Access Denied');
}
class template {
var $subtemplates = array();
var $csscurmodules = '';
var $replacecode = array('search' => array(), 'replace' => array());
var $language = array();
var $file = '';
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')) {
$tpl = $tpldir.'/'.$file.'.htm';
$tplfile = $tplfile != $tpl ? $tpl.'", "'.$tplfile : $tplfile;
echo $tplfile.'template is not found';
}
$template = @fread($fp, filesize(DISCUZ_ROOT.$tplfile));
fclose($fp);
$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 = str_replace("{LF}", "<?=\"\\n\"?>", $template);
$template = preg_replace("/[\n\r\t]*\{eval\s+(.+?)\s*\}[\n\r\t]*/ies", "\$this->evaltags('\\1')", $template);
$template = preg_replace("/\{(\\\$[a-zA-Z0-9_\-\>\[\]\'\"\$\.\x7f-\xff]+)\}/s", "<?=\\1?>", $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 .= ';';
}
$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')) {
echo dirname(DISCUZ_ROOT.$cachefile).'directory is not found';
}
$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);
}
function stripphpcode($type, $code) {
$this->phpcode[$type][] = $code;
return '{phpcode:'.$type.'/'.(count($this->phpcode[$type]) - 1).'}';
}
function loadsubtemplate($file) {
$tplfile = template($file, 0, '', 1);
if($content = @implode('', file(DISCUZ_ROOT.$tplfile))) {
$this->subtemplates[] = $tplfile;
return $content;
} else {
return '<!-- '.$file.' -->';
}
}
function transamp($str) {
$str = str_replace('&', '&', $str);
$str = str_replace('&', '&', $str);
$str = str_replace('\"', '"', $str);
return $str;
}
function addquote($var) {
return str_replace("\\\"", "\"", preg_replace("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s", "['\\1']", $var));
}
function stripvtags($expr, $statement = '') {
$expr = str_replace("\\\"", "\"", preg_replace("/\<\?\=(\\\$.+?)\?\>/s", "\\1", $expr));
$statement = str_replace("\\\"", "\"", $statement);
return $expr.$statement;
}
function stripscriptamp($s, $extra) {
$extra = str_replace('\\"', '"', $extra);
$s = str_replace('&', '&', $s);
return "<script src=\"$s\" type=\"text/javascript\"$extra></script>";
}
function evaltags($php) {
$php = str_replace('\"', '"', $php);
$i = count($this->replacecode['search']);
$this->replacecode['search'][$i] = $search = "<!--EVAL_TAG_$i-->";
$this->replacecode['replace'][$i] = "<?php $php?>";
return $search;
}
function stripblock($var, $s) {
$s = str_replace('\\"', '"', $s);
$s = preg_replace("/<\?=\\\$(.+?)\?>/", "{\$\\1}", $s);
preg_match_all("/<\?=(.+?)\?>/e", $s, $constary);
$constadd = '';
$constary[1] = array_unique($constary[1]);
foreach($constary[1] as $const) {
$constadd .= '$__'.$const.' = '.$const.';';
}
$s = preg_replace("/<\?=(.+?)\?>/", "{\$__\\1}", $s);
$s = str_replace('?>', "\n\$$var .= <<<EOF\n", $s);
$s = str_replace('<?', "\nEOF;\n", $s);
return "<?\n$constadd\$$var = <<<EOF\n".$s."\nEOF;\n?>";
}
}
?>
基本工作完成。
建立一个文件:
include './config.php';
error_reporting(E_ALL);
include DISCUZ_ROOT.'./global.func.php';
include DISCUZ_ROOT.'./class_template.php';
$a = 'wangjiang';
$b = array(1=>'a',2=>'b',3=>'c');
include template('jump');
OK,可以使用了,详细见附件
点击下载
直接下载就可以使用!
查看完整版本: 剥离DISCUZ X系列的模板引擎机制
为什么不能下载了呢?Tags: discuz