核心概述:它是什么?为什么需要它?
在深入代码之前,我们先要明白它的作用。

它是什么?
dedetemplate.class.php 是一个模板引擎,它的任务不是直接输出 HTML,而是解析 DedeCMS 特有的模板语法(如 {dede:arclist}),并将其转换成最终可执行的 PHP 代码。
为什么需要它? DedeCMS 的目标是生成静态 HTML 文件,以提高网站访问速度和减轻服务器压力,如果每次访问都实时查询数据库、循环标签、拼接 HTML,那静态化就失去了意义,DedeCMS 采用了“编译”模式:
- 模板文件 (
.htm): 开发者编写的、包含 DedeCMS 标签的文件。index.htm。 - 编译文件 (
.php): 由解析类处理.htm文件后生成的纯 PHP 代码文件。index.php,这个文件里已经没有了{dede:...}标签,而是包含了 PHP 的foreach、if等逻辑。 - 最终输出: 网站访问者请求的是编译后的
.php文件,这个文件直接执行,无需再次解析模板,速度极快。
核心流程:
模板文件 (index.htm) -> dedetemplate.class.php 解析编译 -> 编译文件 (index.php) -> Web服务器执行 -> 静态HTML页面
关键类与方法详解
dedetemplate.class.php 文件位于 /include/dedetemplate.class.php,我们来看它的核心成员和方法。

核心成员属性
$tpl: 模板根目录。$cacheDir: 编译文件(缓存)存放目录。$templateDir: 当前模板的目录。$block: 用于存储模板中的块({dede:block})。$file: 当前正在处理的模板文件名。$refCache: 引用缓存,用于优化重复编译。$charsets: 字符集设置。
核心方法
Display($templateFile)
这是最常用、最重要的方法,用于显示一个编译后的模板。
- 功能: 接收一个模板文件名(如
index.htm),检查是否存在对应的编译文件(如index.php),如果不存在或模板已更新,则调用编译方法,include编译后的文件并执行。 - 内部逻辑:
- 确定文件路径: 拼接出模板文件和编译文件的完整路径。
- 检查编译文件: 判断编译文件是否存在,以及模板文件是否比编译文件新(
filemtime)。 - 条件编译: 如果编译文件不存在或模板已修改,则调用
ParseTemplate()方法进行编译。 - 引入并执行: 使用
include或require将编译后的 PHP 文件引入到当前作用域并执行,这一步是生成最终内容的关键。
示例用法:
require_once(DEDEINC.'/arc.partview.class.php'); $pv = new PartView(); $pv->SetTemplet($tplfile); // 设置模板文件,如 'index.htm' $pv->Display(); // 调用 Display 方法
(注:PartView 类是 dedetemplate 的一个封装,实际调用的是其内部的 Display 方法)
ParseTemplate($templateFile)
这是编译过程的核心,负责将模板文件内容转换为 PHP 代码。

- 功能: 读取
.htm文件内容,逐行或逐块解析,将 DedeCMS 标签替换为 PHP 代码,最后写入编译文件。 - 内部逻辑:
- 读取模板内容: 使用
file_get_contents读取整个模板文件。 - 核心正则替换: 这是解析的精髓,它会使用一系列复杂的正则表达式来匹配不同的标签。
- 编译头部: 在生成的 PHP 文件顶部加上版权、字符集、路径等定义。
- 解析全局标签: 如
{dede:global name='cfg_webname'/},替换为<?php echo $cfg_webname; ?>。 - 解析块级标签: 如
{dede:block name='block1'}...{/dede:block},将其中的内容提取出来,并用 PHP 变量存储,方便后续调用。 - 解析普通标签: 这是最复杂的部分,
{dede:arclist titlelen='24' row='10'}。- 它会识别标签名(
arclist)、属性(titlelen='24')和结束符()。 - 它会根据标签名,去
/taglib目录下找到对应的标签库文件(如lib_arclist.php)。 - 它会调用标签库文件中的
lib_arclist()函数,并将解析后的属性数组作为参数传递。 - 标签库函数返回的是一段完整的 PHP 代码,这段代码通常包含一个
foreach循环,用于输出列表。 - 解析类将原始标签替换为这段从标签库返回的 PHP 代码。
- 它会识别标签名(
- 解析内建函数: 如
{dede:field.title function='htmlspecialchars(@me)'/},会被替换为<?php echo htmlspecialchars($fields['title']); ?>。
- 写入编译文件: 将所有替换后的 PHP 代码字符串,通过
file_put_contents写入到.php编译文件中。
- 读取模板内容: 使用
GetTemplate($filename)
一个辅助方法,用于获取编译后的模板内容(即编译文件里的 PHP 代码字符串)。
- 功能: 类似
Display,但它不执行代码,而是返回编译后的 PHP 代码字符串。 - 用途: 在某些需要动态获取模板内容而非直接输出的场景下使用。
ClearAllCache()
清除所有编译文件。
- 功能: 遍历编译目录,删除所有
.php文件。 - 用途: 当网站模板发生大规模更新,或者需要强制重新编译所有页面时使用。
一个简化的解析过程示例
假设我们有这样一个模板片段 list.htm:
{dede:global name='cfg_webname'/}
<ul>
{dede:arclist titlelen='24' row='5'}
<li>[field:title/]</li>
{/dede:arclist}
</ul>
dedetemplate.class.php 的 ParseTemplate 方法处理流程如下:
-
: 获取上面那段 HTML 字符串。
-
处理全局标签:
{dede:global name='cfg_webname'/}-><?php echo $cfg_webname; ?>
-
处理
arclist:- 匹配到
{dede:arclist titlelen='24' row='5'}。 - 解析出标签名
arclist和属性数组['titlelen' => '24', 'row' => '5']。 - 加载
/taglib/lib_arclist.php文件。 - 调用
lib_arclist($ctp, $artlist, $tagid)函数,并将属性数组传递过去。 lib_arclist函数内部会根据这些参数生成一段 PHP 代码,大概是这样:// ... 一些PHP代码,用于查询数据库 foreach($GLOBALS['arcListCache']['artlist'] as $row) { $fields = $row; // ... 一些字段处理 echo "<li>".$fields['title']."</li>"; }- 解析类将原始的
{dede:arclist}...{/dede:arclist}整块替换为上面这段生成的 PHP 代码。
- 匹配到
-
最终编译文件内容: 经过处理后,
list.php文件的内容会是这样的:<?php // 编译头部信息... if(!defined('DEDETEMPLATE')) exit(); echo $cfg_webname; ?> <ul> <?php // ... lib_arclist() 函数生成的PHP代码开始 // 假设这是 lib_arclist 返回的核心部分 $dsql->SetQuery("SELECT title FROM `#@__archives` ... LIMIT 5"); $dsql->Execute('al'); while($row = $dsql->GetArray('al')) { $fields = $row; echo "<li>".cn_substr($fields['title'], 24)."</li>"; } // ... lib_arclist() 函数生成的PHP代码结束 ?> </ul>
当 Display 方法执行 include 'list.php' 时,PHP 引擎会直接运行这段代码,查询数据库并输出最终的 HTML。
总结与最佳实践
dedetemplate.class.php 是 DedeCMS 实现高性能静态化的基石,它通过预编译机制,将开发者友好的模板标签转换为机器友好的 PHP 代码,从而消除了每次请求时的模板解析开销。
最佳实践:
- 不要直接修改编译文件: 编译文件是自动生成的,手动修改会在下次模板更新时被覆盖。
- 理解编译机制: 当你的模板修改后,页面没有更新,很可能是服务器没有写入权限或缓存没有清除,可以尝试后台“更新HTML”或手动删除编译目录下的文件。
- 性能考量: 对于大型网站,
/data/tplcache目录下会积累大量编译文件,确保该目录所在的磁盘有足够空间和良好的 I/O 性能。 - 自定义标签: 深入理解它的工作原理,有助于你开发自己的 DedeCMS 标签,因为自定义标签的编写规范(如
/taglib/xxx.php)正是为了配合这个解析类而设计的。
通过深入理解 dedetemplate.class.php,你不仅能更好地使用 DedeCMS,还能在遇到性能问题时,快速定位到模板编译或执行环节,并进行有效的优化。
