核心思路
织梦的栏目是树状结构(一级栏目 -> 二级栏目 -> 三级栏目...),要在首页调用二级栏目,通常需要两步:

(图片来源网络,侵删)
- 调用一级栏目:首先获取所有顶级栏目。
- 循环调用每个一级栏目下的二级栏目:在循环一级栏目的过程中,对每一个一级栏目,再调用其直接下属的二级栏目。
最常用的嵌套循环方法(推荐)
这是最经典、最灵活的方法,可以实现将一级栏目作为标题,下面列出其所有二级栏目的效果。
标签代码示例
{dede:channelartlist typeid='0' row='8'}
<h2><a href="{dede:field name='typeurl'/}">{dede:field name='typename'/}</a></h2>
<ul>
{dede:channel type='son' noself='yes'}
<li><a href="[field:typelink/]">[field:typename/]</a></li>
{/dede:channel}
</ul>
{/dede:channelartlist}
代码详解
-
外层循环:
{dede:channelartlist ...}- 作用:这个标签专门用于获取顶级栏目及其下属栏目的数据,是实现嵌套栏目的关键。
typeid='0':表示调用所有顶级栏目,如果你想只调用特定的几个一级栏目,可以在这里填写它们的ID,用英文逗号隔开,typeid='1,3,5'。row='8':表示调用的一级栏目数量,这里设置为8个。<h2><a href="{dede:field name='typeurl'/}">{dede:field name='typename'/}</a></h2>:{dede:field name='typeurl'/}:获取当前一级栏目的链接地址。{dede:field name='typename'/}:获取当前一级栏目的名称。- 这部分代码会在页面上显示所有一级栏目的名称,并链接到对应的一级栏目列表页。
-
内层循环:
{dede:channel type='son' noself='yes'}- 作用:这个标签必须在
{dede:channelartlist}的内部使用,用于获取当前一级栏目下的所有子栏目(即二级栏目)。 type='son':指定获取当前栏目的子栏目,这是实现“二级”调用的核心属性。noself='yes':表示不包含栏目自身,因为我们只想显示二级栏目,所以加上这个属性,避免重复显示一级栏目本身。<li><a href="[field:typelink/]">[field:typename/]</a></li>:[field:typelink/]:这是二级栏目的简写形式,等同于{dede:field name='typelink'/},获取二级栏目的链接。[field:typename/]:这是二级栏目的简写形式,等同于{dede:field name='typename'/},获取二级栏目的名称。- 这部分代码会在每个一级栏目名称下面,循环列出其所有二级栏目。
- 作用:这个标签必须在
纯SQL查询方法(更灵活,适合有开发经验的用户)
如果你对SQL语句比较熟悉,并且需要更复杂的筛选条件(例如只调用某个特定模型下的二级栏目),可以使用自定义SQL标签。

(图片来源网络,侵删)
标签代码示例
{dede:sql sql="SELECT id,typename,typedir FROM `#@__arctype` WHERE reid > 0 ORDER BY id ASC"}
<li><a href="[field:typedir function='str_replace("{cmspath}", "", "@me")'/]">[field:typename/]</a></li>
{/dede:sql}
代码详解
-
{dede:sql sql="..."}:- 这是一个执行自定义SQL语句的标签。
SELECT id,typename,typedir FROM#@__arctype``:从织梦的栏目表#@__arctype中查询栏目的ID、名称和目录。WHERE reid > 0:这是关键!reid字段表示“父栏目ID”,顶级栏目的reid为 0,reid > 0的条件就筛选出了所有非顶级栏目,也就是所有二级、三级...栏目。ORDER BY id ASC:按栏目ID升序排列。
-
[field:typedir function='str_replace("{cmspath}", "", "@me")'/]:[field:typedir/]获取到的栏目目录是{cmspath}/a/b/这样的完整格式。function='str_replace("{cmspath}", "", "@me")'是一个自定义函数,用于将{cmspath}这个占位符替换成空,最终得到正确的链接路径/a/b/。
方法二的优缺点
- 优点:
- 非常灵活,可以添加任何SQL条件(如
WHERE channel > 0来筛选某个模型下的栏目)。 - 性能可能略高于标签嵌套(对于数据量大的情况)。
- 非常灵活,可以添加任何SQL条件(如
- 缺点:
- 可读性差,不易维护。
- 需要了解数据库表结构。
- 在多站点或目录变动时,手动处理路径容易出错。
常用属性与技巧
如何限制二级栏目的数量?
在 {dede:channel} 标签中添加 row 属性。
{dede:channel type='son' noself='yes' row='5'}
<!-- 只显示每个一级栏目下的5个二级栏目 -->
<li><a href="[field:typelink/]">[field:typename/]</a></li>
{/dede:channel}
如何为二级栏目添加其他信息,如文章数、栏目图片?
织梦的标签非常强大,可以直接调用。

(图片来源网络,侵删)
{dede:channelartlist typeid='0' row='8'}
<h2>{dede:field name='typename'/}</h2>
<ul>
{dede:channel type='son' noself='yes' row='5'}
<li>
<a href="[field:typelink/]">[field:typename/]</a>
<!-- 调用该二级栏目下的文章数量 -->
<span>([field:ID runphp='yes'] @me = GetArcList(@me, '', '', '', '', '', '', '', '', -1); @me = @me['TotalResult']; [/field:ID])</span>
<!-- 调用栏目图片,如果存在的话 -->
[field:imglink/]
</li>
{/dede:channel}
</ul>
{/dede:channelartlist}
[field:imglink/]:会自动判断是否有栏目图片,如果有则输出<a href='...'><img src='...'></a>,如果没有则不输出任何内容。- 文章数量调用:使用了嵌套的
GetArcList函数,性能开销较大,如果栏目很多,建议在后台用SQL直接更新栏目文章数,然后调用[field:total/]。
调用指定一级栏目下的二级栏目
只需修改外层标签的 typeid 即可。
假设“新闻中心”这个一级栏目的ID是 1。
{dede:channelartlist typeid='1'}
<h2>{dede:field name='typename'/}</h2>
<ul>
{dede:channel type='son' noself='yes'}
<li><a href="[field:typelink/]">[field:typename/]</a></li>
{/dede:channel}
</ul>
{/dede:channelartlist}
这样页面只会显示“新闻中心”这一个一级栏目,以及它下面的所有二级栏目。
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 嵌套循环 | 绝大多数情况,标准、规范的网站结构。 | 代码清晰、易读易维护、织梦官方推荐。 | 灵活性相对SQL略差。 |
| 自定义SQL | 需要复杂筛选、特殊逻辑,或有特定性能优化需求。 | 灵活性极高,性能可能更好。 | 代码晦涩,需要SQL知识,维护成本高。 |
对于绝大多数用户来说,强烈推荐使用方法一(嵌套循环),它已经能满足99%的首页二级栏目调用需求,并且是织梦最标准、最安全的用法。
