下面我将为你提供几种最常用和最可靠的方法,并详细解释其原理和适用场景。

(图片来源网络,侵删)
使用 GetTopid() 函数(最推荐、最简单)
这是织梦官方提供的、专门用于获取当前栏目顶级栏目ID的函数,也是最推荐的方法,它非常简单直接。
原理
GetTopid() 函数会沿着当前栏目的父级栏目路径向上查找,直到找到顶级栏目(即其顶级栏目ID topid 为自身的ID的栏目),并返回这个顶级栏目的ID。
代码示例
假设你在一个栏目列表页(list_article.htm页(article_article.htm)中,想获取当前栏目的顶级栏目ID。
{dede:field name='id' function="GetTopid(@me)" /}
代码解释:

(图片来源网络,侵删)
{dede:field name='id'}:获取当前栏目的ID。function="GetTopid(@me)":将获取到的当前栏目ID作为参数@me传递给GetTopid()函数进行处理。- 这个标签最终输出的就是顶级栏目的ID。
进阶用法:获取顶级栏目的其他信息
如果你不仅需要顶级栏目的ID,还需要它的名称、链接等信息,可以分两步实现:
- 先用上面的方法获取顶级栏目的ID。
- 再用
GetOneType()函数根据这个ID获取整个栏目的信息数组。
{dede:php}
// 1. 获取当前栏目的顶级栏目ID
$topid = GetTopid($GLOBALS['typeid']);
// 2. 根据顶级栏目ID获取栏目信息数组
$topType = GetOneType($topid);
// 3. 现在你可以从 $topType 数组中获取任何你想要的信息
$topTypeName = $topType['typename']; // 顶级栏目名称
$topTypeUrl = GetTypeUrl($topType['id'], $topType['typedir'], $topType['isdefault'], $topType['defaultname'], $topType['ispart'], $topType['namerule2'], $topType['moresite'], $topType['siteurl'], $topType['sitepath']); // 顶级栏目链接
{/dede:php}
<!-- 在模板中输出 -->
顶级栏目名称:{$topTypeName}
顶级栏目链接:<a href="{$topTypeUrl}">{$topTypeName}</a>
手动通过SQL查询(最灵活、最强大)
如果你需要对顶级栏目进行更复杂的筛选、排序或自定义字段查询,直接在数据库中查询是最灵活的方法。
原理
织梦的 dede_arctype 表存储了所有栏目信息,顶级栏目的一个显著特征是,它的 topid 字段值等于它自己的 id 字段值,我们可以利用这个条件来筛选出所有顶级栏目。
代码示例
假设你想获取所有顶级栏目,并在页面上列出它们的名称和链接。

(图片来源网络,侵删)
{dede:sql sql="SELECT id, typename, typedir FROM `#@__arctype` WHERE topid=id ORDER BY id ASC"}
<li>
<a href="[field:typedir function='GetTypeUrl(@me, -1, 0)'/]">[field:typename/]</a>
</li>
{/dede:sql}
代码解释:
dede:sql:织梦的自定义SQL查询标签。SELECT id, typename, typedir FROM#@arctype`从栏目表中选择需要的字段。#@` 是织梦表前缀的占位符。WHERE topid=id:这是关键条件,它只选出顶级栏目。ORDER BY id ASC:按ID升序排列,你可以换成orders字段来按后台设置的排序。[field:typedir function='GetTypeUrl(@me, -1, 0)'/]:使用GetTypeUrl函数正确生成栏目链接,比直接拼接typedir更可靠。
通过 reid 递归查找(适用于已知父级ID的情况)
如果你的栏目层级很深,或者你从一个子栏目开始,想通过它的 reid (父栏目ID) 不断向上查找,直到找到顶级栏目。
原理
reid 字段存储了当前栏目的直接父级栏目的ID,顶级栏目的 reid 为 0,我们可以编写一个循环或递归函数来向上追溯。
代码示例(在PHP代码块中实现)
{dede:php}
// 获取当前栏目的ID
$current_id = $GLOBALS['typeid'];
// 定义一个变量来存储最终的顶级栏目ID
$top_id = 0;
// 循环向上查找,直到找到顶级栏目(reid为0)
while ($current_id > 0) {
// 查询当前栏目的信息
$query = "SELECT id, typename, reid FROM `#@__arctype` WHERE id = $current_id";
$row = $dsql->GetOne($query);
if (!$row) {
break; // 如果没找到,退出循环
}
// 如果reid为0,说明当前栏目就是顶级栏目
if ($row['reid'] == 0) {
$top_id = $row['id'];
$top_name = $row['typename'];
break;
} else {
// 否则,将父级ID设为新的当前ID,继续循环
$current_id = $row['reid'];
}
}
// 输出结果
if ($top_id > 0) {
echo "找到的顶级栏目ID是: " . $top_id . "<br>";
echo "顶级栏目名称是: " . $top_name . "<br>";
} else {
echo "未找到顶级栏目。";
}
{/dede:php}
代码解释:
- 这种方法比
GetTopid()更底层,也更具“探索性”,它模拟了手动查找的过程。 - 在实际开发中,除非有特殊需求,否则不推荐使用此方法,因为
GetTopid()已经封装好了这个过程,更简洁高效。
总结与推荐
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
GetTopid() 函数 |
代码最简洁、官方推荐、性能好 | 灵活性相对较低 | 绝大多数情况下,尤其是在当前栏目页获取其顶级栏目信息。 |
| SQL 查询 | 灵活性最高,可自定义任意条件 | 需要写SQL语句,对新手不友好 | 需要获取所有顶级栏目列表,或根据特定条件(如自定义字段)筛选顶级栏目时。 |
reid 递归查找 |
原理清晰,适合理解栏目结构 | 代码复杂,性能不如内置函数 | 需要手动追溯栏目路径,或在特定PHP逻辑中处理栏目层级关系时。 |
- 如果你只是想在当前页面获取顶级栏目的ID或名称,直接使用方法一
GetTopid()。 - 如果你想在页面上展示所有顶级栏目,或者有复杂的筛选需求,使用方法二
SQL 查询。 - 方法三通常作为了解和学习之用,实际项目中很少需要手动实现。
