先获取指定一级栏目的ID,然后使用这个ID去查询其下的所有二级子栏目,最后循环输出这些二级子栏目的ID和相关信息。

(图片来源网络,侵删)
下面我将提供几种最常用和最有效的方法,从简单到复杂,并附上详细的代码示例和解释。
使用 {dede:channelartlist} 和 {dede:channel} 标签组合(最常用、最推荐)
这种方法最符合织梦的模板标签逻辑,代码清晰,易于理解和维护,它适用于在某个一级栏目页下,展示其所有二级子栏目。
适用场景:
在一级栏目模板(如 list_article_channelid_1.htm)中,调用该一级栏目下的所有二级子栏目及其ID。
代码示例:

(图片来源网络,侵删)
{dede:channelartlist typeid='1'}
<!--
typeid='1' 这里填写你要调用其子栏目的一级栏目的ID。
如果你想在当前一级栏目页下调用其子栏目,可以省略typeid属性,它会自动获取当前栏目ID。
-->
<h2>{dede:field name='typename'/}</h2> <!-- 这里显示一级栏目的名称 -->
<ul class="sub-cat-list">
{dede:channel type='son' noself='yes'}
<!--
type='son' 表示调用当前栏目的子栏目。
noself='yes' 表示不调用栏目本身。
-->
<li>
<!-- 子栏目链接 -->
<a href="[field:typelink/]">
<!-- 子栏目名称 -->
[field:typename/]
</a>
<!--
重点:这里就是调用二级子栏目ID的方法。
使用[field:id/]即可获取当前子栏目的ID。
-->
<span>栏目ID: [field:id/]</span>
</li>
{/dede:channel}
</ul>
{/dede:channelartlist}
代码解释:
{dede:channelartlist}: 这个标签用于循环顶级栏目或指定的一级栏目,我们用它来锁定“一级栏目”这个层级。{dede:channel type='son'}: 这个标签嵌套在channelartlist内部,它的作用是循环当前channelartlist所指向栏目的子栏目。type='son'是关键参数。[field:id/]: 这是织梦的底层字段标签,在任何{dede:channel}或{dede:arclist}等循环标签内部,[field:xxx/]都用来获取当前循环项的属性。[field:id/]就是获取当前这个子栏目的ID。
使用SQL直接查询(最灵活、功能最强)
当你需要进行更复杂的判断,或者需要在非标准模板页面(如首页、内容页)调用时,直接执行SQL查询是最灵活的方式。
适用场景:
- 在首页调用指定一级栏目的所有二级子栏目ID。
- 需要根据二级子栏目ID进行二次筛选或数据统计。
- 方法一无法满足的复杂需求。
代码示例:

(图片来源网络,侵删)
{dede:sql sql="SELECT id,typename,typedir FROM `#@__arctype`
WHERE reid > 0 AND topid = 1
ORDER BY id ASC"}
<!--
SQL语句解释:
1. SELECT id,typename,typedir: 选择我们需要的字段:ID、栏目名称、栏目目录。
2. FROM `#@__arctype`: 从织梦的栏目表 `dede_arctype` 中查询,`#@__` 是织梦的前缀占位符。
3. WHERE reid > 0: 这是判断是否为子栏目的关键,reid字段记录了其父栏目的ID,reid > 0 说明它不是顶级栏目。
4. AND topid = 1: topid字段记录了其顶级栏目的ID,这里我们限定只查找顶级栏目ID为1的子栏目。
如果你只想找某个一级栏目(假设其ID为5)的直接子栏目,条件应该是 `WHERE reid = 5`。
5. ORDER BY id ASC: 按ID排序,可以根据需要修改为 `orders` 字段。
-->
<li>
<a href="[field:typedir function='str_replace("{cmspath}","",@me)'/]/">
[field:typename/]
</a>
<span>栏目ID: [field:id/]</span>
</li>
{/dede:sql}
代码解释:
reid:父栏目ID,顶级栏目的reid为 0。topid:顶级栏目ID,任何层级的栏目,其topid都是其所属顶级栏目的ID。id:当前栏目的ID。[field:typedir function='str_replace("{cmspath}","",@me)'/]: 因为typedir字段中包含了{cmspath}这样的变量,直接使用会生成错误的链接,这里使用function对其进行字符串替换,移除{cmspath},得到正确的相对路径。
页调用当前文章所在栏目的二级子栏目ID
这个需求比较特殊,比如在一篇文章的详情页,你想列出这篇文章所在一级栏目下的所有兄弟栏目(也就是二级子栏目)。
适用场景:页(article_articleid_X.htm)中,调用与当前文章同属一个一级栏目的所有其他二级子栏目。
代码示例:
<h3>同栏目下的其他栏目</h3>
<ul>
{dede:sql sql="
SELECT id, typename, typedir
FROM `#@__arctype`
WHERE reid = (SELECT reid FROM `#@__arctype` WHERE id = ~typeid~)
AND id != ~typeid~
ORDER BY id ASC
"}
<li>
<a href="[field:typedir function='str_replace("{cmspath}","",@me)'/]/">
[field:typename/]
</a>
<span>栏目ID: [field:id/]</span>
</li>
{/dede:sql}
</ul>
代码解释:
~typeid~: 这是织梦模板中的一个特殊变量,代表当前页面的栏目ID,在内容页中,它等于文章所在栏目的ID。SELECT reid FROM ... WHERE id = ~typeid~: 这是一个子查询,它的作用是先找到当前文章所在栏目的父栏目ID(也就是一级栏目的ID)。WHERE reid = (子查询的结果): 外层查询的条件就变成了查找所有父ID等于这个一级栏目ID的栏目,也就是所有二级子栏目。AND id != ~typeid~: 排除当前文章所在的栏目本身,避免重复。
总结与对比
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 标签组合 | 代码简洁、易读、符合织梦规范、性能较好 | 灵活性相对较低,只能在特定栏目模板中使用 | 最常用,在一级栏目页调用其子栏目 |
| SQL查询 | 极其灵活,可在任何地方调用,可进行复杂筛选 | 代码可读性稍差,需要懂SQL,对不熟悉的人来说有门槛 | 首页调用、复杂条件筛选、非标准页面调用 |
| 内容页SQL | 针对性强,能解决特殊场景问题 | 逻辑较复杂,是方法二的特殊应用 | 在文章页调用同级兄弟栏目 |
对于绝大多数情况,强烈推荐使用方法一,因为它最安全、最易于维护,只有在方法一无法满足需求时,才考虑使用方法二,方法三是方法二在特定场景下的应用。
