核心思路
要获取上级栏目名称,我们通常需要两步:

(图片来源网络,侵删)
- 获取当前栏目的 上级栏目ID(
topid)。 - 根据这个ID,查询数据库或使用DedeCMS的标签获取该上级栏目的 名称(
typename)。
使用 {dede:field} 标签(推荐,最简洁)
这是最简单、最推荐的方法,尤其是在列表页(list_article.htm页(article_article.htm)中,因为当前栏目的信息已经被系统加载好了,可以直接调用。
在列表页(list_article.htm)中使用
在列表页模板中,当前栏目信息通过 global 变量 typename 和 topid 存储。
{dede:global name='typename'/} <!-- 这是当前栏目的名称 -->
{dede:global name='topid'/} <!-- 这是当前栏目的上级栏目ID -->
结合使用,获取上级栏目名称:
{dede:if}
{dede:global name='topid' runphp='yes'}
$topid = @me;
if($topid > 0){
$dsql = new dedesql();
$dsql->SetQuery("SELECT typename FROM `#@_arctype` WHERE id = $topid");
$dsql->Execute('t');
$row = $dsql->GetArray('t');
@me = $row['typename'];
}else{
@me = '顶级栏目';
}
{/dede:global}
{/dede:if}
代码解释:

(图片来源网络,侵删)
{dede:global name='topid' runphp='yes'}: 获取当前栏目的topid,并开启PHP运行。$topid = @me;: 将获取到的ID赋值给PHP变量$topid。if($topid > 0): 判断是否为顶级栏目。topid为0,则表示当前栏目就是顶级栏目。new dedesql(): 创建一个数据库查询对象。SetQuery(...): 编写SQL查询语句,从#@_arctype(栏目表) 中根据id查找typename(栏目名称)。Execute('t')和GetArray('t'): 执行查询并获取结果到数组$row中。@me = $row['typename'];: 将查询到的栏目名称赋值给@me,@me是模板引擎中用于替换输出内容的变量。else { @me = '顶级栏目'; }: 如果是顶级栏目(topid为0),则输出“顶级栏目”或留空。
页(article_article.htm)中使用
页的逻辑与列表页类似,只是获取 topid 的方式不同。
{dede:field name='typeid' runphp='yes'}
$typeid = @me;
$dsql = new dedesql();
$dsql->SetQuery("SELECT topid FROM `#@_arctype` WHERE id = $typeid");
$dsql->Execute('t');
$row = $dsql->GetArray('t');
$topid = $row['topid'];
if($topid > 0){
$dsql->SetQuery("SELECT typename FROM `#@_arctype` WHERE id = $topid");
$dsql->Execute('t');
$row = $dsql->GetArray('t');
@me = $row['typename'];
}else{
@me = '顶级栏目';
}
{/dede:field}
代码解释:
{dede:field name='typeid' runphp='yes'}: 首先获取当前文章的栏目ID (typeid)。- 然后通过这个
typeid去查询#@_arctype表,得到它的topid。 - 接下来的步骤与方法一在列表页中的完全一样。
使用SQL标签(灵活,适用于所有页面)
如果你觉得PHP代码在模板中不够优雅,或者想在首页等其他页面使用,可以完全用SQL标签来实现。
这个方法的核心是写一个关联查询,一次性获取上级栏目名称。

(图片来源网络,侵删)
在列表页(list_article.htm)中使用
{dede:sql sql="SELECT b.typename as top_typename FROM `#@_arctype` a LEFT JOIN `#@_arctype` b ON a.topid = b.id WHERE a.id = ~typeid~"}
[field:top_typename/]
{/dede:sql}
代码解释:
SELECT b.typename as top_typename: 从b表(别名)中选取typename,并命名为top_typename。FROM#@_arctypea LEFT JOIN#@_arctypeb ON a.topid = b.id: 将栏目表自连接。a代表当前栏目,b代表上级栏目,连接条件是a的topid等于b的id。WHERE a.id = ~typeid~: 筛选条件,a.id就是当前栏目的ID。~typeid~是DedeCMS列表页模板中一个特殊的变量,会自动被替换为当前栏目的ID。[field:top_typename/]: 输出查询结果中的top_typename字段。
页(article_article.htm)中使用
页需要先获取 typeid,再嵌入到SQL中。
{dede:sql sql="SELECT b.typename as top_typename FROM `#@_arctype` a LEFT JOIN `#@_arctype` b ON a.topid = b.id WHERE a.id = ~typeid~"}
[field:top_typename/]
{/dede:sql}
注意页,~typeid~ 同样会被系统自动解析为当前文章所属的栏目ID,所以SQL语句是完全一样的。
修改PHP文件(功能增强,适合开发者)
如果你需要在整个网站系统中都方便地调用上级栏目名称,并且不想在每个模板里都写SQL或PHP,可以修改DedeCMS的核心文件来增加一个全局变量。
以修改 include/common.inc.php 为例(此方法有一定风险,请先备份文件):
-
打开
include/common.inc.php文件。 -
找到类似
//全局功能类的位置,在其下方添加一个函数:// 获取指定栏目的上级栏目名称 function GetTopTypename($typeid) { global $dsql; $row = $dsql->GetOne("SELECT topid FROM `#@_arctype` WHERE id = $typeid"); if ($row['topid'] == 0) { return '顶级栏目'; } $topRow = $dsql->GetOne("SELECT typename FROM `#@_arctype` WHERE id = {$row['topid']}"); return $topRow['typename']; } -
在模板中调用: 在任何你需要的模板文件中(如
head.htm),使用PHP代码调用这个函数:<?php // 在列表页,当前栏目ID可以用$GLOBALS['typeid']获取 if(isset($GLOBALS['typeid'])){ echo GetTopTypename($GLOBALS['typeid']); } // 在内容页,当前栏目ID可以用$arcid获取,但需要先转换成typeid // 或者直接使用$GLOBALS['typeid'],在内容页$GLOBALS中也存在 ?>或者,如果你想在
{dede:}标签中使用,可以创建一个自定义标签(这需要更深入的开发知识)。
总结与建议
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 方法一 (PHP) | 代码直观,逻辑清晰,性能较好 | 模板中嵌入PHP代码,对初学者稍显复杂 | 列表页、内容页的首选 |
| 方法二 (SQL) | 纯模板标签,代码简洁 | SQL关联查询,如果数据量大性能可能略低 | 列表页、内容页,也适用于首页等 |
| 方法三 (PHP文件) | 一劳永逸,全站通用 | 修改核心文件,有升级被覆盖的风险,不适合普通用户 | 需要在多个公共模板(如head.htm)中频繁调用时 |
对于绝大多数用户,强烈推荐使用方法一,因为它在性能和易用性之间取得了最好的平衡,如果你是模板开发者,追求代码的纯粹性,方法二也是一个不错的选择。
