下面我将为你详细讲解如何调用二级栏目,并提供多种场景下的代码示例,从简单到复杂,确保你能完全理解并应用到你的网站中。

核心思路
调用二级栏目的核心思路是 “先调用父栏目,然后在父栏目循环内,调用其子栏目”,这就像一个嵌套循环:
- 外层循环:遍历所有一级(父)栏目。
- 内层循环:对于每一个一级栏目,再遍历它下面的所有二级(子)栏目。
基础标签解析
在开始写代码前,我们先快速回顾一下会用到的几个核心标签:
-
{dede:channel}:用于获取栏目列表。type='top':获取所有顶级(一级)栏目。reid='0':与type='top'效果类似,指定父栏目ID为0。typeid='父栏目ID':这是关键,用于获取指定父栏目下的子栏目。row='数字':获取栏目的数量。col='数字':每行显示多少个栏目(通常用于横向排列)。currentstyle='':当前栏目的样式模板。
-
[field:typename/]:在{dede:channel}循环内,用于获取当前栏目的名称。
(图片来源网络,侵删) -
[field:typelink/]:在{dede:channel}循环内,用于获取当前栏目的链接地址。
调用所有一级栏目及其对应的二级栏目(最常用)
这是最常见的需求,比如网站主导航下面带一个下拉子菜单。
实现逻辑:
- 用一个
{dede:channel type='top'}循环来获取所有一级栏目。 - 在这个循环内部,再嵌套一个
{dede:channel typeid='父栏目ID'}循环来获取当前一级栏目下的所有二级栏目。
代码示例:

<ul class="main-nav">
{dede:channel type='top' row='8'}
<li class="nav-item">
<!-- 一级栏目名称和链接 -->
<a href="[field:typelink/]]" class="nav-link">[field:typename/]</a>
<!-- 二级栏目容器 -->
<ul class="sub-nav">
<!-- 关键:typeid='[field:id/]' 获取当前一级栏目的ID,作为查询子栏目的条件 -->
{dede:channel typeid='[field:id/]'}
<li>
<!-- 二级栏目名称和链接 -->
<a href="[field:typelink/]]" class="sub-link">[field:typename/]</a>
</li>
{/dede:channel}
</ul>
</li>
{/dede:channel}
</ul>
代码解释:
{dede:channel type='top' row='8'}: 循环输出最多8个一级栏目。<a href="[field:typelink/]" ...>: 输出一级栏目的链接和名称。{dede:channel typeid='[field:id/]'}: 这是嵌套循环的核心。[field:id/]会获取外层循环中当前一级栏目的ID,并将其传递给内层循环的typeid属性,从而精确地获取该一级栏目下的所有二级栏目。- 内层的
[field:typelink/]和[field:typename/]则分别输出二级栏目的链接和名称。
调用指定ID的一级栏目及其二级栏目
有时候你可能只想在某个特定位置(比如首页的某个模块)显示某个一级栏目及其子栏目。
实现逻辑:
与场景一类似,只是外层循环的 typeid 不再是动态获取,而是直接指定为你想要的一级栏目的ID。
代码示例:
假设你要调用ID为 2 的一级栏目及其所有子栏目。
<div class="specific-category">
<h3>产品中心</h3> <!-- 这里可以写死一级栏目名称,或者也用标签调用 -->
<ul>
{dede:channel typeid='2'} <!-- 直接指定父栏目ID为2 -->
<li>
<a href="[field:typelink/]">[field:typename/]</a>
</li>
{/dede:channel}
</ul>
</div>
注意: 这个例子只调用了二级栏目,如果你想同时显示一级栏目名称,可以这样做:
<div class="specific-category">
<!-- 先调用一级栏目信息 -->
{dede:channel typeid='2' row='1'}
<h3><a href="[field:typelink/]">[field:typename/]</a></h3>
{/dede:channel}
<!-- 再调用其子栏目 -->
<ul>
{dede:channel typeid='2'}
<li>
<a href="[field:typelink/]">[field:typename/]</a>
</li>
{/dede:channel}
</ul>
</div>
调用指定栏目ID路径下的所有层级的栏目(递归调用)
织梦的 channel 标签本身不支持无限层级的递归,但如果你需要调用一个栏目及其所有后代栏目(比如做一个网站地图),可以使用 arclist 标签配合SQL查询来实现,或者使用自定义函数,但对于绝大多数“一级+二级”的需求,场景一的方法已经足够。
实战应用:带当前栏目高亮的导航菜单
这是一个非常实用的功能,能让用户清楚地知道自己当前在哪个栏目下。
实现逻辑:
使用 currentstyle 属性,当循环到的栏目是当前页面所在的栏目时,currentstyle 里的内容会被替换掉。
代码示例:
假设当前页面是在“新闻中心”下的“公司新闻”里。
<ul class="main-nav">
{dede:channel type='top' row='8' currentstyle="<li class='nav-item active'><a href='~typelink~' class='nav-link'>~typename~</a></li>"}
<li class="nav-item">
<a href="[field:typelink/]" class="nav-link">[field:typename/]</a>
<ul class="sub-nav">
{dede:channel typeid='[field:id:]' currentstyle="<li class='active'><a href='~typelink~'>~typename~</a></li>"}
<li>
<a href="[field:typelink/]" class="sub-link">[field:typename/]</a>
</li>
{/dede:channel}
</ul>
</li>
{/dede:channel}
</ul>
currentstyle 语法说明:
~typename~会被替换为当前栏目的名称。~typelink~会被替换为当前栏目的链接。- 整个
currentstyle的字符串会替换掉默认的<li>...</li>
这样,当你在“公司新闻”页面时,一级栏目“新闻中心”和二级栏目“公司新闻”都会被 active 样式标记出来。
总结与注意事项
- 核心是嵌套:先父后子,循环嵌套”的原则。
typeid是关键:在子栏目循环中,typeid='[field:id:]'是获取父栏目ID并传递给子查询的核心语法。- ID必须正确:确保你的栏目ID是正确的,否则调用不到任何内容,你可以在后台“栏目管理”中查看每个栏目的ID。
- CSS配合:HTML结构需要配合CSS样式才能实现漂亮的下拉菜单等效果,上面的代码提供了基本的HTML结构,你需要自己编写CSS来控制显示和隐藏、布局等。
- 性能考虑:如果栏目非常多,嵌套循环可能会对页面加载速度有轻微影响,但对于大多数中小型网站来说,这种影响可以忽略不计。
希望这份详细的教程能帮助你彻底掌握在织梦中调用二级栏目的方法!如果你有更具体的需求,可以随时提出。
