DedeCMS 的代码结构非常经典,遵循 MVC (Model-View-Controller) 的思想,尽管它没有严格使用这个术语。

- Model (模型): 数据库表结构,如
dede_archives(文章主表),dede_addonarticle(文章附加表)。 - View (视图): 模板文件,如
article_article.htm(文章内容页),list_default.htm(列表页)。 - Controller (控制器): PHP 处理脚本,如
article_edit.php(后台编辑),article.php(前台内容页)。
核心数据库表结构 (Model)
理解普通文章,首先要理解它的数据存储方式,它主要涉及两张表:
dede_archives (文章主表)
这张表存储所有文章的通用信息,与文章模型无关。
| 字段名 | 说明 | 示例值 |
| :--- | :--- | :--- |
| id | 文章ID (主键) | 123 |
| typeid | 所属栏目ID | 5 |
| typeid2 | 所属副栏目ID | 0 |
| arcrank | 会员级别 (0:公开, -1:审核, 1:会员) | 0 |
| click | 点击次数 | 1024 | | 文章标题 | "DedeCMS 普通文章代码详解" |
| senddate | 发布时间 (时间戳) | 1678886400 |
| mid | 发布会员ID | 1 (管理员) |
| ismake | 是否生成静态页 | 1 (是) |
dede_addonarticle (文章附加表)
这张表存储普通文章模型特有的信息,比如文章内容、来源、作者等,它的 aid 字段与 dede_archives 表的 id 字段关联。
| 字段名 | 说明 | 示例值 |
| :--- | :--- | :--- |
| aid | 文章ID (关联 archives.id) | 123 |
| body | 文章正文内容 (使用HTML) | <p>这里是文章的详细内容...</p> |
| description | | "本文详细介绍了DedeCMS普通文章的代码..." |
| source | 文章来源 | "DedeCMS官网" |
| author | 文章作者 | "张三" |
| litpic | 文章缩略图 | /uploads/2025/02/thumb_123.jpg |
后台发布与编辑代码 (Controller & View)
当你后台点击“[新增普通文章]”或编辑文章时,涉及到以下核心文件:

后台模板文件 (/templets/article_add.htm)
这是你看到的文章发布表单的HTML结构,它定义了标题、栏目、内容等输入框。
<!-- 文件路径: /dede/templets/article_add.htm -->
<form name="addarc" action="article_add.php" method="post" enctype="multipart/form-data">
<!-- 标题输入框 -->
<input type="text" name="title" value="" />
<!-- 栏目选择 -->
<select name="typeid">
<!-- 这里是PHP动态生成的栏目列表 -->
{dede:channel type='son' currentstyle="<option value='~id~' selected>~typename~</option>"}
<option value="[field:id/]">[field:typename/]</option>
{/dede:channel}
</select>
<!-- 缩略图上传 -->
<input type="file" name="litpic" />
<!-- -->
<textarea name="description"></textarea>
<!-- 文章编辑器 (核心内容区) -->
<textarea name="body" id="body"></textarea>
<!-- 这里的id="body" 对应PHP处理脚本中的 $_POST['body'] -->
<!-- 发布按钮 -->
<button type="submit">提交</button>
</form>
后台处理脚本 (/dede/article_add.php)
当你点击提交后,这个PHP文件会接收表单数据,进行数据处理,并写入数据库。
// 文件路径: /dede/article_add.php
require_once(dirname(__FILE__)."/config.php");
CheckPurview('a_New,a_AccNew');
// 1. 接收并处理表单数据
$title = cn_substrR($title, $cfg_title_maxlen); // 处理标题
$typeid = intval($typeid); // 处理栏目ID
$description = cn_substrR($description, 250); // 处理摘要
$body = HtmlReplace($body, -1); // 处理文章内容,过滤危险标签
// 2. 写入主表 dede_archives
$inQuery = "INSERT INTO `dede_archives`(
`typeid`, `arcrank`, `click`, `title`, `senddate`, `mid`, `ismake`
) VALUES (
'$typeid', '$arcrank', '$click', '$title', '".time()."', '$uid', '$ismake'
)";
$dsql->ExecuteNoneQuery($inQuery);
$aid = $dsql->GetLastID(); // 获取刚刚插入文章的ID
// 3. 写入附加表 dede_addonarticle
$inQueryAdd = "INSERT INTO `dede_addonarticle`(
`aid`, `body`, `description`, `source`, `author`, `litpic`
) VALUES (
'$aid', '$body', '$description', '$source', '$author', '$litpic'
)";
$dsql->ExecuteNoneQuery($inQueryAdd);
// 4. 生成HTML文件 (根据配置)
if($cfg_rewrite == 'Y')
{
MakeHtml($aid);
}
else
{
$artUrl = MakeArt($aid);
}
// 5. 提示成功并跳转
ShowMsg("成功发布一篇新文章!", "content_list.php");
核心逻辑:
- 分离数据:将通用数据(标题、时间)存入主表
archives。 - 关联写入:获取新文章的
ID,然后将特有数据(正文、存入附加表addonarticle,并用aid关联起来。 - 生成页面:根据系统配置,动态生成HTML文件或直接使用动态链接。
前台调用代码 (View & Controller)
前台展示文章,主要通过模板标签(Dede标签)从数据库读取数据并渲染成HTML。

页 (/templets/default/article_article.htm)
这是当用户点击一篇文章后看到的页面,它的核心是调用当前文章的详细信息。
<!-- 文件路径: /templets/default/article_article.htm -->
{dede:include filename="head.htm" /} <!-- 加载头部 -->
<!-- 文章标题和元信息 -->
<h1>{dede:field.title/}</h1>
<div class="info">
发布时间:{dede:field.senddate function="MyDate('Y-m-d H:i',@me)"/}
作者:{dede:field.author/}
来源:{dede:field.source/}
</div>
<!-- 文章缩略图 (如果有) -->
{dede:field name='litpic' alt='{dede:field.title/}'}
<img src="{dede:field name='litpic'/}" alt="{dede:field.title/}" />
{/dede:field}
<!-- (通常在列表页用,内容页也可用) -->
<div class="summary">
{dede:field.description function='cn_substr(@me, 200)'/}...
</div>
<!-- 文章正文 (核心内容区) -->
<div class="content">
{dede:field.body/}
</div>
<!-- 文章标签 -->
<div class="tags">
标签:{dede:tag row='5' getall='0'}<a href='[field:tagurl/]'>[field:tag/]</a>{/dede:tag}
</div>
{dede:include filename="footer.htm" /} <!-- 加载底部 -->
核心标签:
{dede:field.title/}: 输出文章标题。{dede:field.body/}: 最重要的标签,输出文章的完整正文内容(来自addonarticle.body)。{dede:field.description/}: 输出文章摘要。{dede:field.senddate/}: 输出发布时间戳,通常配合function函数格式化。
文章列表页 (/templets/default/list_default.htm)
这是栏目页,用于展示该栏目下的所有文章摘要。
<!-- 文件路径: /templets/default/list_default.htm -->
{dede:include filename="head.htm" /}
<h2>{dede:field.typename/}</h2> <!-- 栏目标题 -->
<ul class="list">
<!-- 循环输出文章列表 -->
{dede:list pagesize='10'} <!-- 每页10条 -->
<li>
<a href="[field:arcurl/]">[field:title/]</a> <!-- 文章链接和标题 -->
<span class="date">[field:pubdate function="MyDate('Y-m-d', @me)"]</span> <!-- 发布日期 -->
<p class="intro">[field:description function='cn_substr(@me, 100)'/]...</p> <!-- -->
</li>
{/dede:list}
</ul>
<!-- 分页条 -->
<div class="page">
{dede:pagelist listitem="info,index,end,pre,next,pageno" listsize="5"/}
</div>
{dede:include filename="footer.htm" /}
核心标签:
{dede:list}: 循环标签,用于遍历当前栏目的文章列表。[field:arcurl/]: 生成文章的URL链接。[field:title/]: 输出文章标题。[field:description/]: 输出文章摘要。{dede:pagelist}: 生成分页导航。
前台控制器 (/article.php)
当用户访问一个文章链接(如 https://yourdomain.com/article/123.html)时,/article.php 脚本会被调用,它的作用是:
- 从URL中解析出文章ID (
aid)。 - 根据
aid从dede_archives和dede_addonarticle两张表中查询出文章的所有数据。 - 加载对应的模板文件(如
article_article.htm)。 - 将查询到的数据填充到模板标签中。
- 输出最终的HTML页面。
这是一个简化的 article.php 核心逻辑:
// 文件路径: /article.php (简化版)
require_once(dirname(__FILE__)."/include/common.inc.php");
$aid = isset($aid) && is_numeric($aid) ? $aid : 0;
// 从主表和附加表联合查询文章数据
$query = "SELECT a.*, t.* FROM `dede_archives` a LEFT JOIN `dede_addonarticle` t ON a.id=t.aid WHERE a.id=$aid";
$dsql->SetQuery($query);
$dsql->Execute();
$row = $dsql->GetArray();
if(!is_array($row)) {
ShowMsg('您查看的文章不存在或已被删除!', '-', 0, 5000);
exit();
}
// 更新点击次数
$dsql->ExecuteNoneQuery("UPDATE `dede_archives` SET click=click+1 WHERE id=$aid");
// 将数据分配给模板
$GLOBALS['field'] = $row;
// 加载并解析模板
$pv = new PartView();
$pv->SetTemplet($cfg_basedir.$cfg_templets_dir.'/'.$cfg_df_style.'/article_article.htm');
$pv->Display();
| 功能模块 | 核心文件/代码 | 说明 |
|---|---|---|
| 数据存储 | dede_archives, dede_addonarticle |
主存通用信息,附加表存文章正文等特有信息。 |
| 后台发布 | /dede/templets/article_add.htm (表单)/dede/article_add.php (处理逻辑) |
表单收集数据,PHP脚本处理并写入数据库,生成页面。 |
| 页 | /templets/default/article_article.htm (模板)/article.php (控制器) |
article.php 读取数据,article_article.htm 模板渲染显示。 |
| 前台列表页 | /templets/default/list_default.htm (模板) |
使用 {dede:list} 标签循环调用文章数据。 |
理解了这个流程,你就能明白 DedeCMS 普通文章从发布到展示的完整生命周期,也方便你进行二次开发和模板修改。
