核心思路
无论使用哪种方法,核心思路都是一样的:

(图片来源网络,侵删)
- 获取当前栏目的 ID:DedeCMS 有一个全局变量
$typeid,它存储了当前页面的栏目 ID。 - 根据父栏目 ID 查询子栏目:使用 DedeCMS 提供的标签或函数,在数据库中查询
dede_arctype表,找出所有topid(父栏目 ID) 等于当前栏目 ID 的栏目。 - 循环输出子栏目信息:将查询到的子栏目列表进行循环,并输出每个子栏目的名称、链接、缩略图等信息。
使用 {dede:channelartlist} 标签 (推荐,最灵活)
这是最推荐的方法,因为它不仅限于获取子栏目,还能在一个标签内轻松实现“当前父栏目 + 其所有子栏目”的列表展示,常用于制作侧边栏导航。
适用场景:制作一个包含当前栏目及其所有子栏目的列表。
代码示例:
{dede:channelartlist typeid='top'}
<dl>
<dt><a href='{dede:field name='typeurl'/}'>{dede:field name='typename'/}</a></dt>
<dd>
<ul>
{dede:channel type='son' noself='yes'}
<li>
<a href="[field:typelink/]">[field:typename/]</a>
</li>
{/dede:channel}
</ul>
</dd>
</dl>
{/dede:channelartlist}
代码详解:
-
{dede:channelartlist typeid='top'}typeid='top':这个参数非常重要,它告诉标签从顶级栏目开始循环,它会循环遍历所有顶级栏目。- 工作原理:当你在某个子栏目页面时,
typeid='top'会找到该子栏目的顶级父栏目,并将其作为当前循环项,然后在{dede:channel type='son'}中,就会列出这个顶级父栏目的所有直接子栏目(也就是当前栏目的兄弟栏目和它自己)。 - 注意:如果你只想获取当前栏目的直接子栏目,而不是整个父级分支,这个方法可能需要配合一些 PHP 代码来实现,因为它主要是为了展示“父-子”结构。
-
{dede:field name='typeurl'/}和{dede:field name='typename'/}这两个标签用于输出当前循环项(即父栏目)的链接和名称。
-
{dede:channel type='son' noself='yes'}type='son':指定此标签用于获取当前父栏目的直接子栏目。noself='yes':可选参数,表示不包含当前栏目本身,如果不需要,可以去掉。[field:typelink/]和[field:typename/]:用于输出每个子栏目的链接和名称。
使用 {dede:channel} 标签 (最简单)
如果你只需要获取当前栏目的直接子栏目,并且不需要显示父栏目本身,这个方法最简单直接。
适用场景:仅在当前位置下方列出它的直接子栏目。
代码示例:
<ul>
{dede:channel type='son' typeid=''}
<li>
<a href="[field:typelink/]">[field:typename/]</a>
</li>
{/dede:channel}
</ul>
代码详解:
{dede:channel type='son' typeid=''}:type='son':表示获取子栏目。typeid='':这里留空,系统会自动使用当前页面的栏目 ID ($typeid) 作为父栏目 ID 进行查询,这是最常用的写法。
[field:typelink/]和[field:typename/]:同上,输出子栏目的链接和名称。
使用 PHP 代码 (最灵活,可定制性最强)
如果你需要对子栏目数据进行更复杂的处理(例如按特定字段排序、获取自定义字段、进行二次开发等),直接使用 PHP 代码是最佳选择。
适用场景:需要高度自定义子栏目列表的显示逻辑。
代码示例:
<?php
// 1. 获取当前栏目ID
$typeid = $typeid;
// 2. 使用DedeCMS的GetSonIds函数获取所有子栏目ID(包括孙栏目)
// 如果你只需要直接子栏目,请使用SQL查询
// $sonids = GetSonIds($typeid);
// 3. 直接查询数据库获取直接子栏目
global $dsql;
$sql = "SELECT id, typename, typedir, litpic FROM `#@__arctype` WHERE `topid` = $typeid ORDER BY sortrank ASC";
$dsql->SetQuery($sql);
$dsql->Execute();
echo "<ul>";
while ($row = $dsql->GetArray()) {
// 处理栏目链接,确保以 /
$typeurl = GetTypeUrl($row['id'], $row['typedir'], $row['isdefault'], $row['defaultname'], $row['ispart'], $row['namerule2']);
echo "<li>";
echo "<a href='{$typeurl}'>{$row['typename']}</a>";
// 如果需要,可以在这里输出缩略图
// if (!empty($row['litpic'])) {
// echo "<img src='{$row['litpic']}' alt='{$row['typename']}'>";
// }
echo "</li>";
}
echo "</ul>";
?>
代码详解:
$typeid = $typeid;:获取当前栏目的 ID。$sql = "SELECT ...":编写 SQL 查询语句,从#@__arctype表(dede_arctype)中查询所有topid等于当前$typeid的栏目。ORDER BY sortrank ASC:按照后台设置的“排序值”进行升序排列。
$dsql->Execute();:执行查询。while ($row = $dsql->GetArray()):循环遍历查询结果,每次循环$row就是一个子栏目的数组数据。GetTypeUrl(...): 这是一个 DedeCMS 内置的函数,用于根据栏目信息生成正确的 URL 地址,比直接拼接$row['typedir']更可靠。echo "...":在循环体内,你可以自由地输出任何你想要的信息,如栏目名称、链接、缩略图$row['litpic']、描述等。
总结与对比
| 方法 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
{dede:channelartlist} |
结构清晰,一次标签搞定“父+子”列表,适合导航栏。 | 逻辑相对复杂,不适合只获取直接子栏目。 | 制作网站侧边栏、主导航下拉菜单等。 |
{dede:channel} |
代码最简单,直接明了,专为获取子栏目设计。 | 功能相对固定,自定义能力较弱。 | 在列表页、内容页下方简单地展示子栏目列表。 |
| PHP 代码 | 灵活性最高,可进行任何复杂的数据处理和判断。 | 需要了解 PHP 和 SQL,对新手不友好。 | 需要自定义排序、获取自定义字段、或进行复杂逻辑判断时。 |
对于大多数情况,方法二 ({dede:channel}) 是最常用、最简单的选择,如果你需要制作一个包含父级导航的复杂列表,方法一 ({dede:channelartlist}) 则是更好的选择。
