核心思路
织梦调用子栏目的核心标签是 {dede:channel},它的关键属性是:

(图片来源网络,侵删)
type='top': 调用顶级栏目(一级栏目)。reid='栏目ID': 调指定栏目ID下的子栏目(二级栏目)。typeid='栏目ID': 指定当前栏目ID,通常与reid配合使用,实现高亮等效果。
要调用三级栏目,基本思路就是:
- 先调用一级栏目。
- 在一级栏目循环中,调用当前一级栏目下的二级栏目。
- 在二级栏目循环中,调用当前二级栏目下的三级栏目。
这就构成了一个“三层嵌套”的结构。
最常用和推荐的方法(三层嵌套)
这种方法结构清晰,易于理解和维护,适用于绝大多数网站布局。
适用场景
网站有明确的栏目层级,首页 -> 产品中心 -> 手机 -> iPhone 14,需要分别展示一级、二级、三级栏目。

(图片来源网络,侵删)
代码示例
假设我们要在首页调用所有三级栏目,代码如下:
{dede:channel type='top' row='8'}
<!-- 第一层循环:调用一级栏目 -->
<dl>
<dt><a href="[field:typelink/]">[field:typename/]</a></dt>
<!-- 第二层循环:调用当前一级栏目下的二级栏目 -->
{dede:channel type='son' reid='[field:id]'}
<dd>
<!-- 第三层循环:调用当前二级栏目下的三级栏目 -->
{dede:channel type='son' reid='[field:id]'}
<a href="[field:typelink/]">[field:typename/]</a>
{/dede:channel}
</dd>
{/dede:channel}
</dl>
{/dede:channel}
代码详解
-
第一层:
{dede:channel type='top' row='8'}type='top': 表示调用顶级栏目,即所有的一级栏目。row='8': 限制只调用8个一级栏目。[field:id]: 当前一级栏目的ID。[field:typename]: 当前一级栏目的名称。[field:typelink]: 当前一级栏目的链接地址。
-
第二层:
{dede:channel type='son' reid='[field:id]'}- 这个标签嵌套在第一层循环内部。
type='son': 表示调用子栏目。reid='[field:id]': 这是关键! 它的值是第一层循环中当前一级栏目的ID ([field:id]),这样,织梦就知道要调用哪个一级栏目下的二级栏目了。
-
第三层:
{dede:channel type='son' reid='[field:id]'}
(图片来源网络,侵删)- 这个标签嵌套在第二层循环内部。
- 同样使用
type='son'和reid属性。 - 这里的
[field:id]是第二层循环中当前二级栏目的ID。reid='[field:id]'就表示调用当前二级栏目下的所有三级栏目。
渲染后的HTML结构
<dl>
<dt><a href="/plus/list.php?tid=1">产品中心</a></dt>
<dd>
<a href="/plus/list.php?tid=11">手机</a>
<!-- 这是三级栏目 -->
<a href="/plus/list.php?tid=111">iPhone 14</a>
<a href="/plus/list.php?tid=112">华为 Mate 60</a>
</dd>
<dd>
<a href="/plus/list.php?tid=12">电脑</a>
<!-- 这是三级栏目 -->
<a href="/plus/list.php?tid=121">MacBook Pro</a>
<a href="/plus/list.php?tid=122">联想小新</a>
</dd>
</dl>
<dl>
<dt><a href="/plus/list.php?tid=2">新闻资讯</a></dt>
<dd>
<a href="/plus/list.php?tid=21">公司动态</a>
<!-- 这是三级栏目 -->
<a href="/plus/list.php?tid=211">最新公告</a>
</dd>
...
</dl>
只获取指定一级栏目下的三级栏目
我们只想在某个特定的一级栏目下(产品中心”)展示它的三级栏目,而不是全站的所有栏目。
适用场景
在“产品中心”这个页面的侧边栏,展示其下的所有手机、电脑等品牌(三级栏目)。
代码示例
假设“产品中心”这个一级栏目的ID是 1。
<!-- 假设这是在 typeid=1 的页面模板中 -->
<h2>产品系列</h2>
<ul>
{dede:channel type='son' reid='1'}
<!-- 第二层:先获取“产品中心”下的二级栏目(如“手机”、“电脑”) -->
<li>
<span>[field:typename/]</span>
<ul>
<!-- 第三层:在二级栏目循环内,获取其下的三级栏目 -->
{dede:channel type='son' reid='[field:id]'}
<li><a href="[field:typelink/]">[field:typename/]</a></li>
{/dede:channel}
</ul>
</li>
{/dede:channel}
</ul>
代码详解
- 与方法一的核心逻辑完全相同,区别在于第一层循环。
- 这里我们不再使用
type='top',而是直接使用reid='1'来锁定ID为1的“产品中心”这个一级栏目。 - 后面的两层嵌套逻辑不变,继续向下挖掘二级和三级栏目。
使用SQL直接查询(高级用法)
对于一些非常复杂的查询或者需要高度自定义的情况,可以直接使用织梦的SQL标签 {dede:sql}。
适用场景
需要非常灵活地筛选栏目,比如只调用某个特定栏目下的三级栏目,并且需要按特定字段排序等。
代码示例
假设我们要获取ID为 1 的一级栏目下的所有三级栏目。
{dede:sql sql="SELECT id, typename, typelink FROM `dede_arctype` WHERE reid IN (SELECT id FROM `dede_arctype` WHERE reid = 1)"}
<a href="[field:typelink/]">[field:typename/]</a>
{/dede:sql}
代码详解
dede_arctype是织梦存放栏目信息的表。reid IN (SELECT id FROM ... WHERE reid = 1)是这个SQL的核心。SELECT id FROM dede_arctype WHERE reid = 1: 这句查询会找出所有reid为1的栏目,也就是ID为1的一级栏目下的所有二级栏目的ID列表。reid IN (...): 外层的查询则找出所有reid等于内层查询返回的ID列表中的任何一个的栏目,这些栏目,自然就是二级栏目的子栏目——也就是三级栏目。
注意:使用SQL标签需要你对数据库表结构有一定了解,并且要注意SQL注入的风险,虽然织梦本身有处理,但也要谨慎。
总结与建议
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 三层嵌套 | 代码清晰,易于理解和维护,符合织梦标签化思想。 | 如果层级很深,代码会显得冗长。 | 最常用,推荐首选,适用于绝大多数网站栏目调用。 |
| 指定ID | 目标明确,只调用需要的部分,页面更简洁。 | 需要手动知道目标栏目的ID。 | 调用特定父栏目下的子栏目,如侧边栏。 |
| SQL查询 | 灵活度极高,可以完成任何复杂的查询逻辑。 | 代码可读性差,对新手不友好,有一定风险。 | 需要高度自定义或无法用标签实现的复杂查询。 |
对于99%的需求,强烈推荐使用方法一(三层嵌套),因为它最符合织梦的设计哲学,也最容易被团队其他成员理解和维护。
