场景分析
我们需要明确“第一个子栏目”的具体含义:

(图片来源网络,侵删)
- 按后台排序顺序:这是最常见的需求,在后台添加栏目时,可以通过“排序”字段来控制栏目的显示顺序,我们通常需要获取排序值最小的那个子栏目。
- 按ID顺序:即栏目ID最小的子栏目,这种方法不太常用,因为栏目ID是后台添加时自增的,与显示顺序无关。
- 按字母或拼音顺序:按栏目名称的拼音或首字母排序,这种情况较少。
默认情况下,我们按照“后台排序顺序”来讲解。
使用 {dede:channel} 标签(最推荐、最简单)
这是最直接、最织梦化的方法,通过 typeid 和 row 属性来精确控制。
适用场景:你已经知道父栏目的ID。
标签语法:

(图片来源网络,侵删)
{dede:channel type='son' typeid='父栏目ID' row='1'}
<a href="[field:typelink/]">[field:typename/]</a>
{/dede:channel}
参数详解:
typeid='父栏目ID':必填,指定要获取子栏目的父栏目ID,你的“产品中心”栏目ID是3,这里就填3。type='son':表示获取指定栏目的直接子栏目(一级子栏目),如果使用type='selfson',则会获取所有层级的子栏目(包括孙栏目),但row='1'只会取到第一个。row='1':核心,表示只获取1条记录,也就是第一个符合条件的子栏目。[field:typelink/]:子栏目的链接地址。[field:typename/]:子栏目的名称。
完整示例(假设父栏目ID为5):
<div class="first-sub-category">
<h3>推荐子栏目:</h3>
{dede:channel type='son' typeid='5' row='1'}
<a href="[field:typelink/]" title="[field:typename/]">[field:typename/]</a>
{/dede:channel}
</div>
使用 {dede:sql} 直接查询数据库(最灵活)
当你不知道父栏目ID,或者需要更复杂的排序逻辑时(比如按拼音排序),可以直接使用SQL语句查询。
适用场景:
- 父栏目ID是动态的(当前所在栏目的父级)。
- 需要自定义排序规则(如按字母、按点击量等)。
- 需要获取除排序外的更多字段信息。
SQL语句:
SELECT id, typename, typedir, url FROM `#@__arctype` WHERE reid = 父栏目ID ORDER BY sortrank ASC LIMIT 1
参数详解:
reid = 父栏目ID:reid是 DedeCMS 栏目表#@__arctype中存储父栏目ID的字段,这是筛选子栏目的关键。ORDER BY sortrank ASC:核心。sortrank是后台的“排序”字段。ASC表示升序(从小到大),这样就能保证获取到排序值最小的第一个子栏目,如果你想按ID取,就用ORDER BY id ASC。LIMIT 1:只取一条结果。
在模板中的使用:
{dede:sql sql="SELECT id, typename, typedir FROM `#@__arctype` WHERE reid=5 ORDER BY sortrank ASC LIMIT 1"}
<a href="[field:typedir function='str_replace("{cmspath}", "", "@me")'/]">[field:typename/]</a>
{/dede:sql}
注意事项:
[field:typedir/]的值可能包含{cmspath},需要使用function='str_replace("{cmspath}", "", "@me")'来处理,才能得到正确的相对路径。- 这种方法直接操作数据库,效率很高,但需要你对SQL有一定了解。
使用PHP代码(最强大、最灵活)
如果你的需求非常复杂,或者想在PHP层面进行更复杂的判断和逻辑处理,可以使用PHP代码。
适用场景:
- 需要结合多个条件判断。
- 需要在获取子栏目后,再进行二次处理。
- 需要配合其他PHP函数或变量。
实现步骤:
- 在你的模板文件中(通常是
index.htm),找到需要插入代码的位置。 - 将以下PHP代码粘贴进去。
<?php
// 1. 获取数据库实例
$dsql = $GLOBALS['dsql'];
// 2. 定义父栏目ID
$parent_id = 5; // <--- 请在这里替换成你的父栏目ID
// 3. 编写SQL查询
$sql = "SELECT id, typename, typedir
FROM `#@__arctype`
WHERE reid = {$parent_id}
ORDER BY sortrank ASC
LIMIT 1";
// 4. 执行查询
$row = $dsql->GetOne($sql);
// 5. 判断是否查询到结果,并输出
if(is_array($row)) {
// 处理路径,去除 {cmspath}
$typeDir = str_replace('{cmspath}', '', $row['typedir']);
echo "<a href='{$typeDir}'>{$row['typename']}</a>";
} else {
// 如果没有子栏目,可以输出提示或什么都不做
// echo "<span>暂无子栏目</span>";
}
?>
代码详解:
$dsql = $GLOBALS['dsql'];获取DedeCMS的全局数据库对象。$parent_id = 5;设置你要查询的父栏目ID。GetOne()方法是DedeCMS的$dsql对象的一个便捷方法,用于执行查询并直接返回第一条记录(一个关联数组)。is_array($row)判断查询是否成功返回了结果。- 我们使用PHP的
echo将HTML代码输出到模板中。
总结与选择建议
| 方法 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
{dede:channel} |
代码最简洁、最符合织梦规范、执行效率高 | 需要提前知道父栏目ID,灵活性稍差 | 绝大多数情况下的首选,特别是父栏目ID固定时。 |
{dede:sql} |
非常灵活,可以写任意SQL,能获取所有字段 | 需要了解SQL,路径处理稍显麻烦 | 父栏目ID不确定,或需要自定义复杂排序逻辑时。 |
| PHP代码 | 功能最强大,可以处理任何复杂逻辑 | 代码量稍多,对PHP有一定要求 | 需要在PHP层面进行复杂判断、循环或与其他PHP功能结合时。 |
对于绝大多数用户来说,方法一 ({dede:channel}) 是最简单、最直接、也是最应该优先考虑的解决方案。
