场景设定
为了方便理解,我们先设定一个网站栏目结构:

(图片来源网络,侵删)
- 一级栏目 (顶级栏目)
- 产品中心 (ID假设为
1)- 二级栏目 A (ID假设为
5) - 二级栏目 B (ID假设为
6) - 二级栏目 C (ID假设为
7)
- 二级栏目 A (ID假设为
- 新闻资讯 (ID假设为
2)- 公司新闻 (ID假设为
8) - 行业动态 (ID假设为
9)
- 公司新闻 (ID假设为
- 产品中心 (ID假设为
我们的目标是:在某个页面(比如首页)中,只调用“产品中心”下的所有二级栏目(即 A, B, C)。
使用 {dede:sql} 标签(最灵活、最常用)
这是最直接、最强大的方法,你可以直接执行SQL语句来获取你需要的数据。
基础调用:调用指定顶级栏目下的所有直接子栏目(二级栏目)
假设我们要调用顶级栏目“产品中心”(ID=1)下的所有二级栏目。
代码示例:

(图片来源网络,侵删)
{dede:sql sql='SELECT * FROM `dede_arctype` WHERE topid = 1 AND ishidden = 0 ORDER BY orderby'}
<li>
<a href="[field:typedir function='MakePublicHtml(@me)'/]">[field:typename/]</a>
</li>
{/dede:sql}
代码解析:
sql='...':这里是你要执行的SQL查询语句。dede_arctype:这是织梦存储栏目的数据表名,请确认你的表名是否一致(有时可能是#@__arctype)。WHERE topid = 1:这是筛选条件。topid字段存储的是该栏目的顶级栏目ID。topid = 1表示只查找顶级栏目ID为1的栏目,也就是“产品中心”的直接子栏目。AND ishidden = 0:这是一个推荐的附加条件,ishidden = 0表示只调用在后台设置为“隐藏”的栏目,如果你需要调用所有栏目,可以去掉这句。ORDER BY orderby:按后台设置的排序方式进行排序。[field:typedir function='MakePublicHtml(@me)'/]:获取栏目的链接地址。MakePublicHtml函数会自动处理链接,确保格式正确。[field:typename/]:获取栏目的名称。
进阶调用:调用指定顶级栏目下的所有子栏目(包括多级)
如果你不仅想调用二级栏目,还想调用“产品中心”下的所有层级的子栏目(比如三级、四级栏目),可以使用 reid 字段。
代码示例:
{dede:sql sql='SELECT * FROM `dede_arctype` WHERE reid = 1 AND ishidden = 0 ORDER BY orderby'}
<li>
<a href="[field:typedir function='MakePublicHtml(@me)'/]">[field:typename/]</a>
</li>
{/dede:sql}
代码解析:
WHERE reid = 1:reid字段存储的是该栏目的父栏目ID。reid = 1表示查找所有父栏目ID为1的栏目,这包括了“产品中心”的直接子栏目(二级)和间接子栏目(三级、四级等)。
使用 {dede:channel} 标签(更织梦化、推荐)
{dede:channel} 标签是织梦专门用于调用栏目的,使用它更符合织梦的习惯,并且自带了一些缓存机制,性能更好。
调用指定顶级栏目下的直接子栏目
{dede:channel} 标签有一个 typeid 属性,但它通常用于指定从哪个栏目开始调用,要调用指定顶级栏目的子栏目,我们需要结合 topid 自定义属性。
代码示例:
{dede:channel type='son' typeid='1'}
<li>
<a href="[field:typedir/]">[field:typename/]</a>
</li>
{/dede:channel}
代码解析:
type='son':表示调用指定栏目的直接子栏目。typeid='1':表示以哪个栏目为基准,这里的1是顶级栏目“产品中心”的ID。type='son'会自动查找typeid所指栏目的所有子栏目。[field:typedir/]和[field:typename/]:与sql标签中的用法类似,用于获取链接和名称。
注意:{dede:channel} 标签默认不包含 ishidden 的判断,所以它会调用所有子栏目,包括在后台隐藏的,如果需要排除隐藏栏目,仍然推荐使用方法一的 {dede:sql}。
调用指定顶级栏目下的所有子栏目(包括多级)
{dede:channel} 标签可以通过设置 type='self' 来调用指定栏目及其所有下级栏目。
代码示例:
{dede:channel type='self' typeid='1'}
<li>
<a href="[field:typedir/]">[field:typename/]</a>
</li>
{/dede:channel}
代码解析:
type='self':表示调用指定栏目(typeid)及其所有下级栏目,它会递归地查找所有层级的子栏目。
在列表页或内容页调用当前栏目的子栏目
这是一个非常实用的场景,比如在“产品中心”列表页,你想同时列出它下面的所有二级栏目。
这时,你不需要手动填写ID,而是使用织梦的全局变量 typeid。
代码示例(在列表页 list_article.htm 或内容页 article_article.htm 中):
{dede:channel type='son' typeid='~typeid~'}
<a href="[field:typedir/]">[field:typename/]</a> |
{/dede:channel}
代码解析:
typeid='~typeid~':这是织梦的变量替换语法。~typeid~会被当前页面的栏目ID自动替换,如果你在“产品中心”(ID=1)的列表页,~typeid~就会变成1,效果与方法二中的typeid='1'完全一样。- 这种方法的好处是代码可复用,无论你把这个代码放到哪个栏目的模板里,它都能自动调用该栏目自己的子栏目。
总结与对比
| 方法 | 适用场景 | 优点 | 缺点 | |
|---|---|---|---|---|
| 方法一 | {dede:sql} |
任意页面,需要精确控制查询条件时 | 最灵活,可以写任意复杂的SQL,能精确控制查询(如排除隐藏栏目)。 | 需要懂一些SQL,代码可读性稍差。 |
| 方法二 | {dede:channel} |
任意页面,调用栏目列表时 | 更符合织梦规范,性能较好(有缓存),代码简洁。 | 灵活性不如sql标签,默认无法排除隐藏栏目。 |
| 方法三 | {dede:channel} |
列表页或内容页,调用当前栏目的子栏目 | 高度自动化,无需手动指定ID,模板复用性强。 | 仅限于在已有栏目上下文中使用。 |
推荐实践:
- 如果只是简单地调用一个顶级栏目的子栏目,优先使用 方法二 (
{dede:channel}),代码更简洁。 - 如果需要排除后台隐藏的栏目,或者有更复杂的筛选逻辑(比如只调用某个特定条件的栏目),必须使用 方法一 (
{dede:sql})。 - 在列表页或内容页调用当前栏目的子栏目,毫无疑问使用 方法三 (
{dede:channel}结合~typeid~)。
希望这些详细的解释和示例能帮助你顺利实现织梦指定二级栏目的调用!
