使用 {dede:channelartlist} 标签(最推荐、最灵活)
这是实现该需求最标准、最强大的方法。{dede:channelartlist} 标签可以循环获取一个父栏目及其所有子栏目,然后在循环内部使用 {dede:arclist} 标签来调用每个子栏目的文章列表。

(图片来源网络,侵删)
适用场景:
- 需要在一个页面上清晰地展示“子栏目名称”及其下的所有文章列表。
- 布局要求每个子栏目的列表是独立分开的。
示例代码:
{dede:channelartlist typeid='top'}
<h2><a href="{dede:field name='typeurl'/}">{dede:field name='typename'/}</a></h2>
<ul>
{dede:arclist titlelen='42' row='10'}
<li>
<a href="[field:arcurl/]">[field:title/]</a>
<span>[field:pubdate function="MyDate('Y-m-d', @me)"/]</span>
</li>
{/dede:arclist}
</ul>
{/dede:channelartlist}
代码详解:
-
{dede:channelartlist typeid='top'}typeid='top': 这是关键参数,表示获取顶级栏目,如果你的当前页面本身就是某个栏目页,并且你想调用它的直接子栏目,你应该把top换成当前栏目的 ID。- 当前栏目 ID 是
5,那么就应该写成typeid='5'。 - 这个标签会循环遍历所有符合条件的子栏目。
-
<h2><a href="{dede:field name='typeurl'/}">{dede:field name='typename'/}</a></h2>- 在
{dede:channelartlist}的循环体内,{dede:field}标签默认指向的是当前循环的子栏目。 {dede:field name='typename'}: 输出当前子栏目的名称。{dede:field name='typeurl'}: 输出当前子栏目的链接地址。
- 在
-
{dede:arclist titlelen='42' row='10'}- 这个标签嵌套在
channelartlist内部,它的作用域被限定在当前循环的子栏目内。 titlelen='42': 限制文章标题的长度为 42 个字符。row='10': 调用当前子栏目下的 10 篇文章。- 你可以在这个标签内使用所有
arclist支持的参数,如orderby='hot'(按点击排序)、idlist=''(指定文章ID) 等。
- 这个标签嵌套在
使用 {dede:list} 标签(在子栏目页直接调用)
如果你的需求是在子栏目自己的列表页中,调用该栏目及其所有下级栏目的文章列表,那么直接使用 {dede:list} 并配合一个参数即可。

(图片来源网络,侵删)
适用场景:
- 你在子栏目 A 的列表页 (
plus/list-3-1.html),想同时看到 A 和 A 的所有子栏目(B, C, D)的文章。 - 这种方式会将所有文章混在一起显示,不再区分栏目。
示例代码:
{dede:list pagesize='10'}
<li>
<a href="[field:arcurl/]">[field:title/]</a>
<span>[field:pubdate function="MyDate('Y-m-d', @me)"/]</span>
</li>
{/dede:list}
如何实现调用下级栏目?
这需要修改 DedeCMS 的核心文件,操作前请务必备份!
- 打开文件
/include/arc.listview.class.php。 - 找到大约第 740 行左右的代码(不同版本行号可能略有差异):
$this->dsql->SetQuery("Select id,typename,typedir,isdefault,isdefault,defaultname,namerule2,moresite,siteurl,sitepath From `dede_arctype` WHERE reid='$reid' And ishidden<>1 order by sortrank asc"); - 将
WHERE reid='$reid'修改为WHERE reid='$reid' OR topid='$reid'。reid='$reid':获取当前栏目的直接子栏目。OR topid='$reid':获取当前栏目的所有子孙级栏目(即下级栏目及其更深层的栏目)。
- 保存文件并上传到服务器。
完成以上修改后,在任何子栏目页使用 {dede:list} 标签,都会自动获取该栏目及其所有下级栏目的文章列表。
使用 SQL 查询(最灵活,适合复杂需求)
如果你需要非常自定义的输出,或者需要结合其他复杂条件,可以直接在模板中使用 SQL 查询。
适用场景:
- 需要调用指定子栏目的文章,并按特定字段排序。
- 需要调用文章的自定义字段,
arclist标签不支持。 - 需要对结果进行二次筛选或处理。
示例代码:
{dede:sql sql='
SELECT
a.id, a.title, a.pubdate, a.typeid, t.typename, t.typedir
FROM
dede_archives a
LEFT JOIN
dede_arctype t ON a.typeid = t.id
WHERE
a.typeid IN (SELECT id FROM dede_arctype WHERE reid=~typeid~)
ORDER BY
a.pubdate DESC
LIMIT
0, 20
'}
<li>
<a href="[field:typedir/]/[field:id/].html">[field:title/]</a>
<span>[field:pubdate function="MyDate('Y-m-d', @me)"/]</span>
</li>
{/dede:sql}
代码详解:
{dede:sql sql='...'}: 执行自定义的 SQL 语句。~typeid~: 这是 DedeCMS 模板中的一个特殊变量,代表当前页面的栏目 ID,SQL 查询会自动将其替换为实际的数字 ID。WHERE a.typeid IN (SELECT id FROM dede_arctype WHERE reid=~typeid~):- 这是一个子查询,它首先会执行
SELECT id FROM dede_arctype WHERE reid=~typeid~,找出当前栏目下所有直接子栏目的 ID。 IN关键字会确保a.typeid(文章的栏目ID)是这些子栏目 ID 中的一个。- 这个条件保证了我们只查询到子栏目下的文章。
- 这是一个子查询,它首先会执行
[field:typedir/]/[field:id/].html: 注意这里的文章链接写法。[field:typedir/]是栏目目录,[field:id/]是文章ID,这样组合可以确保链接正确。
总结与建议
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
{dede:channelartlist} |
结构清晰,代码标准,推荐 | 需要两层循环,代码稍长 | 最常用,需要分块展示不同子栏目列表的情况。 |
{dede:list} (修改核心) |
简单直接,无需额外标签 | 需要修改核心文件,有升级风险,且所有子栏目文章混在一起 | 在子栏目页需要聚合自身及所有下级文章,且不区分栏目。 |
{dede:sql} |
极度灵活,可做任何复杂查询 | 需要懂 SQL 语法,可读性稍差,性能需要自行优化 | 需要高度自定义查询,调用 arclist 不支持的功能或字段。 |
对于绝大多数情况,强烈推荐使用方法一 ({dede:channelartlist}),因为它最符合 DedeCMS 的设计理念,且代码易于维护和理解。

(图片来源网络,侵删)
