使用 {dede:sonchannel} 标签(推荐,最简单)
{dede:sonchannel} 标签的作用是获取并显示指定栏目的直接子栏目(下一级栏目),通过嵌套使用这个标签,可以轻松实现三级、四级甚至更深层级的栏目调用。

(图片来源网络,侵删)
核心思路:
- 先用
{dede:channel}调用一级栏目。 - 在一级栏目循环内部,嵌套一个
{dede:sonchannel}来调用该一级栏目下的二级栏目。 - 在二级栏目循环内部,再嵌套一个
{dede:sonchannel}来调用三级栏目。 - 以此类推,调用四级栏目。
示例:调用三级栏目
假设我们要在首页展示一个包含一级、二级、三级栏目的导航菜单。
<ul class="nav">
{dede:channel type='top' row='8'}
<li class="nav-item">
<a href="[field:typelink/]">[field:typename/]</a>
<!-- 开始调用二级栏目 -->
{dede:sonchannel}
<ul class="sub-nav">
<li><a href="[field:typelink/]">[field:typename/]</a></li>
<!-- 开始调用三级栏目 -->
{dede:sonchannel}
<ul class="third-nav">
<li><a href="[field:typelink/]">[field:typename/]</a></li>
</ul>
{/dede:sonchannel}
<!-- 结束调用三级栏目 -->
</ul>
{/dede:sonchannel}
<!-- 结束调用二级栏目 -->
</li>
{/dede:channel}
</ul>
代码解析:
{dede:channel type='top' row='8'}:调用顶级栏目(一级栏目),最多显示8个。{dede:sonchannel}:在一级栏目循环内部,它会自动获取当前一级栏目ID下的所有直接子栏目(即二级栏目)。- 嵌套的
{dede:sonchannel}:在二级栏目循环内部,它又会获取当前二级栏目ID下的所有直接子栏目(即三级栏目)。 [field:typelink/]和[field:typename/]:分别获取栏目的链接和名称。
示例:调用四级栏目
调用四级栏目的原理与三级完全相同,只需在三级栏目循环内部再嵌套一层 {dede:sonchannel} 即可。

(图片来源网络,侵删)
<ul class="nav-level-1">
{dede:channel type='top' row='10'}
<li>
<a href="[field:typelink/]">[field:typename/]</a>
<!-- 二级栏目 -->
{dede:sonchannel}
<ul class="nav-level-2">
<li>
<a href="[field:typelink/]">[field:typename/]</a>
<!-- 三级栏目 -->
{dede:sonchannel}
<ul class="nav-level-3">
<li>
<a href="[field:typelink/]">[field:typename/]</a>
<!-- 四级栏目 -->
{dede:sonchannel}
<ul class="nav-level-4">
<li><a href="[field:typelink/]">[field:typename/]</a></li>
</ul>
{/dede:sonchannel}
<!-- 结束四级栏目 -->
</li>
</ul>
{/dede:sonchannel}
<!-- 结束三级栏目 -->
</li>
</ul>
{/dede:sonchannel}
<!-- 结束二级栏目 -->
</li>
{/dede:channel}
</ul>
优点:
- 简单直观:标签嵌套逻辑清晰,易于理解和维护。
- 无需SQL:使用织梦自带标签,安全稳定。
缺点:
- 灵活性稍差:如果栏目层级不固定,或者需要跨级调用,此方法会变得非常复杂和臃肿。
使用自定义SQL查询(灵活,功能强大)
当栏目层级非常深,或者需要根据特定条件(如栏目属性、关键字等)调用栏目时,使用自定义SQL会是更好的选择。
核心思路:
直接在模板中使用 dede:sql 标签执行SQL查询,从 dede_arctype 表中获取所需层级的栏目数据。

(图片来源网络,侵删)
示例:调用指定一级栏目下的所有三级和四级栏目
假设我们要调用ID为 1 的一级栏目(产品中心”)下的所有三级和四级栏目。
{dede:sql sql="
SELECT
t3.id, t3.typename, t3.typelink,
t4.id AS id4, t4.typename AS typename4, t4.typelink AS typelink4
FROM
dede_arctype AS t1
LEFT JOIN
dede_arctype AS t2 ON t1.id = t2.reid
LEFT JOIN
dede_arctype AS t3 ON t2.id = t3.reid
LEFT JOIN
dede_arctype AS t4 ON t3.id = t4.reid
WHERE
t1.id = 1 AND t3.ishidden = 0
ORDER BY
t3.sortrank ASC, t4.sortrank ASC
"}
<!-- 三级栏目 -->
<div class="category-group">
<h3>[field:typename/]</h3>
<ul>
<!-- 四级栏目 -->
{dede:sql sql="SELECT id, typename, typelink FROM dede_arctype WHERE reid = '~id~' AND ishidden = 0 ORDER BY sortrank ASC"}
<li><a href="[field:typelink/]">[field:typename/]</a></li>
{/dede:sql}
</ul>
</div>
{/dede:sql}
代码解析:
- 主查询:外层的
dede:sql通过JOIN查询,直接获取ID为1的一级栏目下的所有三级栏目数据,并同时关联出四级栏目的部分信息(这里为了简化,我们只关联了ID和名称)。 - 循环三级栏目:外层循环输出三级栏目。
- 内层查询四级栏目:在三级栏目循环内部,我们使用另一个
dede:sql,这里有一个技巧:~id~是织梦模板中的变量替换语法,它会自动被当前循环中三级栏目的id值替换,这个内层查询会动态地获取每个三级栏目下的所有四级栏目。 ishidden = 0:这是一个非常重要的过滤条件,可以确保调用的是在前台显示的栏目,而不会被隐藏的后台栏目干扰。
优点:
- 极高的灵活性:可以任意组合查询条件,实现非常复杂的调用逻辑。
- 性能可控:通过优化SQL语句,可以获得比多层嵌套标签更好的性能。
- 结构清晰:对于深层级调用,SQL语句比多层嵌套的HTML标签更清晰。
缺点:
- 需要SQL知识:要求使用者对SQL语句有一定的了解。
- 潜在风险:如果SQL写错,可能会导致网站出错或性能下降。
使用PHP代码调用(终极方案)
对于一些非常复杂的动态逻辑,或者需要在调用栏目时进行复杂处理的场景,可以直接在模板中嵌入PHP代码。
核心思路:
使用 <?php ... ?> 标签,通过PHP代码查询数据库,然后使用织梦的 GetList 或手动解析数据并循环输出。
示例:
<?php
// 1. 引入数据库配置文件
require_once(DEDEINC.'/datalistcp.class.php');
// 2. 准备SQL语句,查询一级ID为1下的所有三级栏目
$sql = "SELECT id, typename, typelink, reid FROM dede_arctype WHERE reid IN (SELECT id FROM dede_arctype WHERE reid = 1) AND ishidden = 0 ORDER BY sortrank ASC";
// 3. 执行查询
$dlist = new DataListCP();
$dlist->SetSource($sql);
$dlist->Display();
$dlist->Close();
// 4. 在循环内部调用四级栏目
// 我们需要修改DataListCP类或在循环中手动处理
// 这里展示一个更直接的手动循环方式
?>
<?php
$sql = "SELECT * FROM dede_arctype WHERE reid IN (SELECT id FROM dede_arctype WHERE reid = 1) AND ishidden = 0";
$dsql = new DedeSql(false);
$dsql->SetQuery($sql);
$dsql->Execute();
while($row = $dsql->GetArray()){
echo '<div class="third-cat">';
echo '<h3><a href="'.$row['typelink'].'">'.$row['typename'].'</a></h3>';
// 查询并输出当前三级栏目下的四级栏目
$sql4 = "SELECT id, typename, typelink FROM dede_arctype WHERE reid = ".$row['id']." AND ishidden = 0 ORDER BY sortrank ASC";
$dsql4 = new DedeSql(false);
$dsql4->SetQuery($sql4);
$dsql4->Execute();
echo '<ul>';
while($row4 = $dsql4->GetArray()){
echo '<li><a href="'.$row4['typelink'].'">'.$row4['typename'].'</a></li>';
}
echo '</ul>';
$dsql4->Close();
echo '</div>';
}
$dsql->Close();
?>
优点:
- 功能最强大:可以结合PHP的所有功能,实现任何复杂的逻辑。
- 性能最佳:直接操作数据库,没有标签解析的开销。
缺点:
- 最复杂:代码量最大,对开发者的PHP和织梦内核熟悉程度要求最高。
- 维护困难:代码直接写在模板中,不利于团队协作和后期维护。
总结与建议
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
{dede:sonchannel} 嵌套 |
简单、直观、易维护 | 灵活性差,层级深时代码臃肿 | 栏目层级固定且不深的常规导航菜单 |
| 自定义SQL | 灵活、功能强大、性能可控 | 需要SQL知识,有潜在风险 | 需要复杂查询、跨级调用或特殊条件筛选 |
| PHP代码调用 | 功能最强大,性能最好 | 复杂,维护困难,对开发者要求高 | 极其复杂的动态逻辑,或需要深度定制功能 |
给您的建议:
- 对于90%的网站导航需求:直接使用 方法一 (
{dede:sonchannel}嵌套) 就足够了,这是织梦官方推荐的最标准、最安全的方式。 - 当导航结构复杂或需要特殊筛选时:请使用 方法二 (自定义SQL),它能以最优雅的方式解决复杂问题,是进阶开发者的首选。
- 尽量避免使用方法三:除非您是开发者,并且确实无法用前两种方法解决问题,将业务逻辑与模板分离是更好的实践。
希望这份详细的指南能帮助您成功调用织梦的三级、四级栏目!
