使用 channelartlist + channel (推荐,最灵活)
这种方法是调用二级导航最经典、最强大的方式。channelartlist 用于获取一级栏目,而 channel 嵌套在内部,用于获取每个一级栏目下的二级子栏目。

核心标签说明
{dede:channelartlist}: 用于获取指定的一级栏目列表。typeid='top': 表示调用顶级栏目(即一级栏目)。typeid='1,2,3': 可以指定调用特定的几个一级栏目,用英文逗号隔开。{dede:field name='typename'}: 在循环内部,用于获取当前一级栏目的名称。{dede:field name='typeurl'}: 在循环内部,用于获取当前一级栏目的链接地址。
{dede:channel}: 用于获取指定栏目的子栏目。typeid=''}": 这个标签必须放在channelartlist循环内部,当不指定typeid时,它会自动获取当前channelartlist循环到的那个一级栏目的所有子栏目,这是实现二级导航的关键。row='10': 表示显示的子栏目数量。type='son': 表示获取当前栏目的子栏目,在channelartlist嵌套下,通常可以省略,因为默认行为就是这样。
HTML & 模板代码示例
这是最常用的一种导航结构,通常用于网站的头部主菜单。
<nav class="main-nav">
<ul class="nav-list">
{dede:channelartlist typeid='top' row='8'}
<li class="nav-item">
<!-- 一级栏目链接 -->
<a href="{dede:field name='typeurl'/}" class="nav-link">
{dede:field name='typename'/}
</a>
<!-- 二级栏目列表 -->
<ul class="sub-nav-list">
{dede:channel type='son' row='10'}
<li class="sub-nav-item">
<a href="[field:typelink/]" class="sub-nav-link">[field:typename/]</a>
</li>
{/dede:channel}
<!-- 如果某个一级栏目没有子栏目,可以显示一个空占位或隐藏整个二级菜单 -->
{dede:if empty=''}
<li class="sub-nav-item">暂无子栏目</li>
{/dede:if}
</ul>
</li>
{/dede:channelartlist}
</ul>
</nav>
代码解析
{dede:channelartlist typeid='top' row='8'}: 开始一个循环,获取最多8个顶级栏目(一级导航)。<li class="nav-item">: 每个一级栏目都是一个列表项。<a href="{dede:field name='typeurl'/}">...{dede:field name='typename'/}</a>: 输出一级栏目的链接和名称。{dede:channel type='son' row='10'}: 在一级栏目循环内部,再开始一个循环,获取当前这个一级栏目的所有子栏目(二级导航)。<li><a href="[field:typelink/]">[field:typename/]</a></li>: 输出每个二级栏目的链接和名称。- 注意:在
channel标签内部,使用[field:xxx/]来获取子栏目的信息,而不是{dede:field}。
- 注意:在
{/dede:channel}和{/dede:channelartlist}: 分别闭合两个循环。
使用 arclist 标签 (特定场景下使用)
这种方法比较特殊,适用于某些特定布局,比如在文章列表页或内容页,想调用当前所在一级栏目的所有子栏目。
核心标签说明
{dede:arclist}: 通常用于调用文章列表,但它有一个typeid和son属性可以用来获取栏目。typeid=''}": 指定一个栏目ID。son='1': 表示获取指定typeid栏目的所有子栏目。channel='0': 表示不调用文章,只获取栏目信息。
HTML & 模板代码示例
假设你在文章内容页(article_article.htm),想调用当前文章所在一级栏目的所有兄弟栏目(也就是二级导航)。
<div class="related-channels">
<h3>相关栏目</h3>
<ul>
{dede:arclist typeid='~typeid~' row='20' channel='0'}
<li><a href="[field:typelink/]">[field:typename/]</a></li>
{/dede:arclist}
</ul>
</div>
代码解析
-
typeid='~typeid~': 这是关键。~typeid~是织梦的一个特殊变量,它会自动解析为当前内容所在的二级栏目的ID。
(图片来源网络,侵删) -
son='1': 获取typeid指定栏目的子栏目,因为我们的typeid已经是二级栏目了,son='1'会获取它的三级栏目,这通常不是我们想要的。 -
修正思路: 如果想获取当前一级栏目下的所有子栏目(也就是当前二级栏目的所有兄弟),我们需要获取当前二级栏目的顶级父栏目ID。
更正后的代码应该是这样的:
<div class="related-channels"> <h3>本栏目所有子栏目</h3> <ul> {dede:arclist typeid='~topid~' row='20' channel='0'} <li><a href="[field:typelink/]">[field:typename/]</a></li> {/dede:arclist} </ul> </div>~topid~: 这是另一个特殊变量,它表示当前内容所在栏目的顶级父栏目ID,如果当前栏目本身就是一级栏目,~topid~就等于它自己的ID。
高级技巧:当前栏目高亮
为了让用户体验更好,我们通常需要让当前所在的栏目高亮显示,这可以通过CSS和织梦的条件判断标签来实现。

在一级栏目上判断当前
在 channelartlist 循环中,使用 typeid 和 global.autoindex 来判断。
{dede:channelartlist typeid='top' row='8'}
<li class="nav-item {dede:field name='typeid' function='IsTopID(@me)'/}">
<a href="{dede:field name='typeurl'/}">{dede:field name='typename'/}</a>
<!-- 二级栏目代码... -->
</li>
{/dede:channelartlist}
在你的网站根目录下 include/common.func.php 文件的最后,添加以下自定义函数:
// 判断是否为当前顶级栏目ID
function IsTopID($id)
{
global $cfg_Cs;
$id = intval($id);
if(is_array($cfg_Cs))
{
foreach($cfg_Cs as $key => $value)
{
if($id == $value['id'] || $id == $value['topid']) return 'active';
}
}
return '';
}
在CSS中定义 .active 样式即可。
在二级栏目上判断当前
在 channel 循环中,判断当前栏目的ID是否等于全局变量 typeid(当前页面的栏目ID)。
{dede:channel type='son' row='10'}
<li class="sub-nav-item [field:ID function='IsSonID(@me, "~typeid~")'/]">
<a href="[field:typelink/]">[field:typename/]</a>
</li>
{/dede:channel}
同样,在 include/common.func.php 文件中添加函数:
// 判断是否为当前子栏目ID
function IsSonID($id, $typeid)
{
if($id == $typeid) return 'active';
return '';
}
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
channelartlist + channel |
网站主导航、任何需要调用固定一级栏目及其子栏目的地方 | 结构清晰,逻辑性强,最标准,最推荐 | 代码稍长,需要理解嵌套循环 |
arclist |
页或列表页,动态调用当前相关栏目的子栏目 | 灵活,能根据当前页面内容变化 | 只适用于特定页面,不如第一种通用 |
对于绝大多数情况,强烈推荐使用第一种方法 (channelartlist + channel ),它是织梦调用二级导航最规范、最稳定的方式。
