核心概念解析
我们拆解这三个概念:

(图片来源网络,侵删)
-
{dede:list}:- 作用:这是 DedeCMS 中最核心的列表页标签,用于在列表页(如栏目首页、搜索结果页等)中循环输出内容。
- 默认行为:它默认会调用当前栏目的文章列表,并根据系统设置(如每页显示数量、排序方式等)进行分页。
-
DIY 模式:
- 作用:DIY 模式允许你通过可视化的后台界面,自由拖拽系统内置的标签(如
{dede:list},{dede:field}等)到模板中,从而快速生成页面布局,无需手写大量代码。 - 位置:在后台 -> 模板 -> 模板管理 -> 模板设置 -> 使用DIY模式。
- 核心文件:
/templets/default/list_default.htm(默认的列表页模板,DIY模式就是在这个基础上进行的)。
- 作用:DIY 模式允许你通过可视化的后台界面,自由拖拽系统内置的标签(如
-
数据表:
- 作用:DedeCMS 的所有数据都存储在 MySQL 数据库的表中。
{dede:list}标签默认读取的是dede_archives(主表) 和dede_addonarticle(附加表,用于存储文章内容) 这两张表。 - 扩展性:当默认字段不够用时,我们可以通过自定义数据表来存储新的数据,然后修改
{dede:list}的底层查询,让它从我们自定义的表中读取数据。
- 作用:DedeCMS 的所有数据都存储在 MySQL 数据库的表中。
{dede:list} 标签的底层原理
要实现自定义数据源,我们必须理解 {dede:list} 是如何工作的。

(图片来源网络,侵删)
- 标签解析:当 DedeCMS 解析模板时,遇到
{dede:list}标签,会调用其底层处理文件。 - 核心文件:这个底层逻辑主要在
/include/arc.listview.class.php文件中,这个类负责生成列表页的 SQL 查询语句。 - 默认SQL:在
arc.listview.class.php中,$this->dsql->SetQuery()方法会构建一个类似下面的 SQL 查询:SELECT a.id, a.title, a.litpic, a.pubdate, a.writer FROM dede_archives AS a LEFT JOIN dede_addonarticle AS arc ON a.id = arc.aid WHERE a.arcrank > -1 AND a.typeid = '当前栏目ID' ORDER BY a.sortrank DESC, a.id DESC LIMIT 起始位置, 每页条数
- 数据绑定:查询结果会被循环遍历,并赋值给模板中的
{dede:list}块内的变量,如[field:title/]、[field:litpic/]等。
DIY 模式的作用:就是让你在一个可视化的编辑器里,把 {dede:list} 这个“数据循环块”和里面的 [field:*] 变量像搭积木一样组合起来,形成最终的页面布局。
场景:如何让 {dede:list} 读取自定义数据表?
假设我们有这样一个需求:创建一个“产品展示”列表页,但产品的“价格”和“库存”等信息,我们不想存在 dede_addonarticle 里,而是希望有一个独立的 dede_products 表。
创建自定义数据表
在您的数据库中(如 phpMyAdmin)创建一个新表。
CREATE TABLE `dede_products` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增ID', `aid` int(11) NOT NULL COMMENT '关联的文章ID (对应 dede_archives 表)', `product_name` varchar(255) NOT NULL COMMENT '产品名称', `price` decimal(10,2) NOT NULL COMMENT '价格', `stock` int(11) NOT NULL DEFAULT '0' COMMENT '库存', `brand` varchar(100) NOT NULL COMMENT '品牌', PRIMARY KEY (`id`), KEY `aid` (`aid`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COMMENT='产品信息表';
向主表 dede_archives 插入记录
因为 DedeCMS 的结构是 archives 主表 + 附加表,所以我们需要先在 dede_archives 中创建一个“文章”来作为我们产品的“外壳”。

(图片来源网络,侵删)
INSERT INTO `dede_archives` (
`typeid`, `arcrank`, `channel`, `senddate`, `sortrank`, `ismake`, `arctitle`, `mid`, `click`
) VALUES (
'1', -- 栏目ID,请替换为你的产品栏目ID
'0', -- 审核状态
'1', -- 频道ID,1代表普通文章
UNIX_TIMESTAMP(), -- 发布时间
'0', -- 排序
'1', -- 是否生成静态
'示例产品', -- 文章标题
'1', -- 管理员ID
'0' -- 点击量
);
执行后,记下返回的 id (假设为 100),然后向 dede_products 表插入数据:
INSERT INTO `dede_products` (`aid`, `product_name`, `price`, `stock`, `brand`) VALUES
('100', '高性能服务器', '8999.00', '50', '品牌A');
修改 {dede:list} 的底层查询(核心步骤)
我们需要修改 /include/arc.listview.class.php 文件,让它在处理列表时,能关联上我们的 dede_products 表。
- 打开文件:
/include/arc.listview.class.php - 找到
SelectSql函数:这个函数负责构建最终的 SQL 查询语句。 - 修改 SQL 查询:找到类似
$this->dsql->SetQuery(...)的地方,修改SELECT和JOIN部分。
修改前(大概样子):
// ... 在 SelectSql 函数内部 ...
$query = "SELECT arc.*,tp.typedir,tp.typename,tp.corank,tp.isdefault,tp.defaultname,
tp.namerule,tp.moresite,tp.siteurl,tp.sitepath
FROM `dede_archives` arc
LEFT JOIN `dede_arctype` tp ON arc.typeid=tp.id
WHERE {$this->addSql} $ordersql LIMIT $limitstart,$row";
修改后(关联我们的自定义表):
我们需要确保 arc.id 和 products.aid 关联,arc.id 是主键。
// ... 在 SelectSql 函数内部 ...
// 原来的 FROM 子句
$from = " `dede_archives` arc ";
// 如果当前栏目是产品栏目(比如typeid=5),则关联我们的产品表
if ($this->TypeID == 5) { // <-- 这里替换为你的产品栏目ID
$from .= " LEFT JOIN `dede_products` products ON arc.id = products.aid ";
// 在 SELECT 中加入我们需要的自定义字段
$addfields = ", products.product_name, products.price, products.stock, products.brand";
} else {
$addfields = '';
}
$query = "SELECT arc.*,tp.typedir,tp.typename,tp.corank,tp.isdefault,tp.defaultname,
tp.namerule,tp.moresite,tp.siteurl,tp.sitepath $addfields
FROM $from
LEFT JOIN `dede_arctype` tp ON arc.typeid=tp.id
WHERE {$this->addSql} $ordersql LIMIT $limitstart,$row";
代码解释:
- 我们通过判断当前栏目ID (
$this->TypeID) 来决定是否要关联我们的自定义表。 - 如果是产品栏目,我们就把
FROM子句和JOIN子句修改为关联dede_archives和dede_products。 - 在
SELECT中,我们通过$addfields变量追加了自定义表的字段。
在模板中调用自定义字段
后台的“更新HTML”或“生成栏目”会使用新的SQL查询,你可以在你的列表模板(无论是手写还是DIY模式)中直接使用新字段了。
在DIY模式中:
- 进入后台 -> 模板 -> 模板管理 -> 选择你的产品列表模板 -> 使用DIY模式。
- 拖入一个
{dede:list}标签到编辑区。 - 在
{dede:list}循环块内,像使用普通字段一样使用你的自定义字段:{dede:list} <li> <a href="[field:arcurl/]">[field:title/]</a> <p>产品名称: [field:product_name/]</p> <p>价格: ¥[field:price/]</p> <p>品牌: [field:brand/]</p> </li> {/dede:list} - 保存并生成页面。
总结与最佳实践
| 功能点 | 实现方式 | 优点 | 缺点 |
|---|---|---|---|
| 普通列表 | 使用默认的 {dede:list} 和 dede_archives/dede_addonarticle 表 |
简单、稳定、有后台支持 | 字段扩展受限于附加表结构 |
| DIY 模式列表 | 在后台可视化编辑 {dede:list} 布局 |
无需代码即可调整页面布局 | 底层数据源仍是默认表 |
| 自定义数据表列表 | 修改 arc.listview.class.php 的 SelectSql 函数 |
灵活性极高,可完全自定义数据结构 | 需要修改核心文件,升级时可能被覆盖,有一定技术门槛 |
重要提示:
- 备份:在修改
arc.listview.class.php之前,务必备份原文件。 - 升级:如果你后续升级 DedeCMS,这个修改的文件可能会被新版本覆盖,你需要重新进行修改,最好记录下你的修改步骤。
- 命名规范:自定义数据表和字段名建议使用小写字母和下划线,避免使用特殊字符。
- 性能:合理使用数据库索引(如
aid)可以确保关联查询的效率。
通过以上步骤,你就可以灵活地让 DedeCMS 的列表功能读取任何你想要的数据表,实现高度定制化的网站需求。
