手动嵌套法 和 arclist 标签法。

(图片来源网络,侵删)
准备工作:理解栏目结构
在开始之前,请确保你的网站后台已经正确设置了三级栏目结构,
- 一级栏目 (ID: 1): 公司简介
- 二级栏目 (ID: 2): 发展历程
- 三级栏目 (ID: 3): 2010-2025
- 三级栏目 (ID: 4): 2025-至今
- 二级栏目 (ID: 5): 企业文化
- 三级栏目 (ID: 6): 使命与愿景
- 三级栏目 (ID: 7): 核心价值观
- 二级栏目 (ID: 2): 发展历程
- 一级栏目 (ID: 8): 产品中心
- 二级栏目 (ID: 9): 硬件产品
- 三级栏目 (ID: 10): 服务器
- 三级栏目 (ID: 11): 存储设备
- 二级栏目 (ID: 12): 软件产品
- 三级栏目 (ID: 13): 操作系统
- 三级栏目 (ID: 14): 应用软件
- 二级栏目 (ID: 9): 硬件产品
我们的目标就是把这个结构在前端完美地展示出来。
手动嵌套 channel 标签(最常用、最灵活)
这是最传统也是最推荐的方法,因为它结构清晰,易于理解和控制。
核心逻辑:

(图片来源网络,侵删)
- 第一层
channel:调取所有顶级栏目(reid='0')。 - 第二层
channel:在第一层循环内部,调取当前顶级栏目下的所有二级栏目(reid='typeid')。 - 第三层
channel:在第二层循环内部,调取当前二级栏目下的所有三级栏目(reid='typeid')。
模板代码示例:
<ul class="top-menu">
{dede:channel type='top' row='8'}
<li class="top-item">
<a href="[field:typeurl/]]" title="[field:typename/]]" target="_self">[field:typename/]</a>
<!-- 第二层:调取当前顶级栏目下的二级栏目 -->
{dede:channel type='son' row='10'}
<ul class="sub-menu">
<li class="sub-item">
<a href="[field:typeurl/]" title="[field:typename/]" target="_self">[field:typename/]</a>
<!-- 第三层:调取当前二级栏目下的三级栏目 -->
{dede:channel type='son' row='15'}
<ul class="third-menu">
<li class="third-item">
<a href="[field:typeurl/]" title="[field:typename/]" target="_self">[field:typename/]</a>
</li>
{/dede:channel}
</li>
</ul>
{/dede:channel}
</li>
{/dede:channel}
</ul>
代码解析:
-
{dede:channel type='top' row='8'}:type='top': 只调用顶级栏目(reid=0)。row='8': 最多调用8个顶级栏目。[field:typeurl/]: 栏目链接。[field:typename/]: 栏目名称。
-
{dede:channel type='son' row='10'}:- 这个标签嵌套在顶级栏目循环内部。
type='son': 调用当前顶级栏目(由外层typeid决定)下的所有子栏目(即二级栏目)。row='10': 最多调用10个子栏目。
-
{dede:channel type='son' row='15'}:- 这个标签嵌套在二级栏目循环内部。
type='son': 调用当前二级栏目(由外层typeid决定)下的所有子栏目(即三级栏目)。row='15': 最多调用15个子栏目。
CSS 样式建议:
为了让菜单层级分明,你需要添加一些 CSS 样式来控制显示和隐藏。
/* 一级菜单 */
.top-menu {
list-style: none;
padding: 0;
margin: 0;
display: flex;
}
.top-item {
position: relative;
margin-right: 20px;
}
.top-item a {
display: block;
padding: 10px 15px;
text-decoration: none;
color: #333;
}
/* 二级菜单(默认隐藏) */
.sub-menu {
list-style: none;
padding: 0;
margin: 0;
position: absolute;
top: 100%;
left: 0;
background-color: #f9f9f9;
display: none; /* 默认隐藏 */
min-width: 150px;
}
/* 当鼠标移到一级菜单项时,显示二级菜单 */
.top-item:hover .sub-menu {
display: block;
}
/* 三级菜单(默认隐藏) */
.third-menu {
list-style: none;
padding: 0;
margin: 0;
position: absolute;
top: 0;
left: 100%;
background-color: #f0f0f0;
display: none; /* 默认隐藏 */
min-width: 150px;
}
/* 当鼠标移到二级菜单项时,显示三级菜单 */
.sub-item:hover .third-menu {
display: block;
}
使用 arclist 标签(更简洁,适合固定栏目)
如果你的三级栏目结构比较固定,或者你只想调用某一个特定顶级栏目下的所有三级内容,arclist 标签也是一个非常方便的选择。
核心逻辑:
- 使用
arclist调用一级栏目。 - 在
arclist的循环体内,再嵌套一个arclist来调用其二级子栏目。 - 在二级
arclist的循环体内,再嵌套一个arclist来调用三级子栏目。
模板代码示例:
<ul class="top-menu">
{dede:arclist typeid='0' row='8' titlelen='24'}
<li class="top-item">
<a href="[field:arcurl/]" title="[field:title/]" target="_self">[field:title/]</a>
<!-- 注意:这里的typeid是动态获取的,需要用[field:id/] -->
{dede:arclist typeid='[field:id/]' row='10' titlelen='24'}
<ul class="sub-menu">
<li class="sub-item">
<a href="[field:arcurl/]" title="[field:title/]" target="_self">[field:title/]</a>
<!-- 第三层:typeid同样是动态获取 -->
{dede:arclist typeid='[field:id/]' row='15' titlelen='24'}
<ul class="third-menu">
<li class="third-item">
<a href="[field:arcurl/]" title="[field:title/]" target="_self">[field:title/]</a>
</li>
{/dede:arclist}
</li>
</ul>
{/dede:arclist}
</li>
{/dede:arclist}
</ul>
代码解析:
-
{dede:arclist typeid='0' row='8'}:typeid='0':arclist当typeid为 0 时,会调用顶级栏目列表。[field:arcurl/]: 栏目链接。[field:title/]: 栏目名称。[field:id/]: 当前栏目的 ID,这个 ID 会被传递给内层的arclist。
-
内层的
{dede:arclist typeid='[field:id/]'}:typeid的值是动态获取的,它等于外层循环中当前栏目的 ID,这样就实现了调用子栏目的目的。
注意:
arclist 标签主要用于调用文章列表,但在没有文章的栏目页,它也能正常返回栏目信息,对于纯导航菜单,channel 标签在语义上更准确一些。
总结与对比
| 特性 | channel 标签嵌套法 |
arclist 标签嵌套法 |
|---|---|---|
| 适用场景 | 通用,适合制作无限级或复杂的导航菜单。 | 适合调用有内容的栏目,或者结构固定的导航。 |
| 语义 | 语义更清晰,channel 就是用来调栏目的。 |
arclist 主要用于文章,但也能“曲线救国”调栏目。 |
| 灵活性 | 非常灵活,可以轻松控制不同层级的显示数量和样式。 | 灵活性稍差,但语法更简洁。 |
| 性能 | 性能良好,是官方推荐的做法。 | 性能也良好,但多一层解析。 |
最终建议:
对于绝大多数情况,强烈推荐使用第一种方法(手动嵌套 channel,它是最标准、最稳定、最易于后期维护和扩展的方案。
