面包屑导航(Breadcrumb Navigation)是网站中非常重要的一部分,它清晰地告诉用户当前页面在网站结构中的位置,方便用户返回上级页面,也有利于 SEO 优化。

在 DedeCMS 中,调用面包屑导航非常简单,主要通过内置的 GetTopnav() 函数实现。
最常用、最简单的方法(推荐)
这是 DedeCMS 官方提供的标准方法,适用于绝大多数情况。
修改模板文件
你需要在你希望显示面包屑导航的模板文件中(通常是 head.htm 或 article_article.htm 等内容页模板)的相应位置,加入以下代码:
{dede:field name='position'/}
或者,你也可以使用 GetTopnav() 函数,两者效果基本一致:

{dede:gettopnav}
<a href='[field:typelink/]'>[field:typename/]</a>
{/dede:gettopnav}
代码解析:
{dede:field name='position'/}是一个简写,它会自动解析当前页面的层级关系,并用>符号连接起来,最后形成一个指向各级父级页面的链接。- 一个文章页面的路径是 "首页 > 技术文章 > PHP教程",
{dede:field name='position'/}会自动生成:<a href='首页链接'>首页</a> > <a href='技术文章链接'>技术文章</a> > PHP教程
效果示例
在 article_article.htm 模板中,将 {dede:field name='position'/} 放在 <h1> 标题上方,是一个很好的实践。
<div class="breadcrumb">
{dede:field name='position'/}
</div>
<h1 class="article-title">{dede:field.title/}</h1>
这样,文章页面加载后,就会显示类似下面的面包屑:
首页 > 技术分享 > DedeCMS教程 > dede面包屑导航调用
自定义面包屑导航(高级用法)
默认的面包屑样式或分隔符可能不符合你的网站设计,这时,你可以通过修改 PHP 文件来自定义面包屑的生成逻辑。

修改 include/typelink.class.php 文件
这个文件是 DedeCMS 处理栏目链接的核心文件,我们可以修改它来自定义面包屑的 HTML 结构。
- 用 FTP 或文件管理器打开
/include/typelink.class.php文件。 - 找到
GetPositionLink()函数(大约在第 95 行)。 - 将函数内部的代码替换为以下自定义代码:
/**
* 获取位置导航链接
*
* @access public
* @return string
*/
function GetPositionLink($islink = true)
{
$indexpage = "<a href='".$this->indexUrl."'>".$this->indexName."</a>";
$this->valuePosition = $this->indexName;
$this->valuePositionLink = $this->indexUrl;
$toplevel = true;
$this->optionArray = array();
if( is_array($this->typeArray) )
{
foreach($this->typeArray as $type)
{
if($tplevel)
{
if($islink)
{
// --- 自定义部分开始 ---
// 这里我们构建一个更灵活的数组
$this->optionArray[] = array(
'name' => $this->indexName,
'link' => $this->indexUrl
);
if(!empty($type['typeurl'])) {
$this->optionArray[] = array(
'name' => $type['typename'],
'link' => $type['typeurl']
);
}
// --- 自定义部分结束 ---
}
else
{
$this->valuePosition .= $this->SplitSymbol.$type['typename'];
}
$toplevel = false;
}
else
{
if($islink)
{
// --- 自定义部分开始 ---
$this->optionArray[] = array(
'name' => $type['typename'],
'link' => $type['typeurl']
);
// --- 自定义部分结束 ---
}
else
{
$this->valuePosition .= $this->SplitSymbol.$type['typename'];
}
}
}
}
// 返回标准的面包屑字符串(保持向后兼容)
$this->valuePositionLink = $indexpage;
if( is_array($this->optionArray) )
{
foreach($this->optionArray as $option)
{
$this->valuePositionLink .= $this->SplitSymbol."<a href='".$option['link']."'>".$option['name']."</a>";
}
}
return $this->valuePositionLink;
}
上面的修改主要目的是为了将面包屑信息存储在一个结构化的数组 $this->optionArray 中,方便在模板中循环和自定义输出。
在模板中循环输出自定义面包屑
你可以在模板文件中使用更灵活的标签来调用:
<div class="breadcrumb">
{dede:gettopnav}
<a href="[field:link/]">[field:name/]</a>
{/dede:gettopnav}
</div>
或者,如果你想完全控制每个部分的样式(比如给最后一个链接不加 > 符号),可以这样写:
<div class="breadcrumb">
<a href="{dede:global.cfg_cmsurl/}/">首页</a>
{dede:field name='position' runphp='yes'}
$tcarr = explode('<a', $refObj->Fields['position']);
$tcarr = array_slice($tcarr, 1, count($tcarr)-2);
$position = '';
foreach($tcarr as $k => $v){
if($k==0) continue;
$v = trim($v);
$v = preg_replace('/^([^>]+)>/', '', $v);
$v = preg_replace('/<\/a>$/', '', $v);
$position .= '<a'.$v.'></a> / ';
}
$position = preg_replace('/\/ $/', '', $position);
echo $position;
{/dede:field}
</div>
注意: 这种 runphp='yes' 的方法非常强大,但语法比较复杂,容易出错,不推荐新手使用。方法一和方法二的第一种自定义方式已经足够应对 99% 的需求。
常见问题与解决方案 (FAQ)
Q1: 为什么我的面包屑只显示 "首页 > 当前栏目名",没有显示更上层的栏目?
A: 这通常是因为你的上级栏目没有被设置为“最终栏目列表页面”(即,上级栏目本身也发布内容,并且你访问的是它的内容页)。
- 检查栏目设置:登录 DedeCMS 后台,进入“频道管理” -> “栏目管理”,检查你的上级栏目。
- 选择正确的栏目类型:
- 如果一个栏目下还有子栏目,它应该被设置为“外部链接”(可以留空)或“频道封面”,这样,它就不会被当作一个内容页来处理。
- 只有最底层的、用来发布文章的栏目,才应该设置为“文章列表”。
- 确保栏目“最终列表页”指向正确:检查栏目的“高级选项” -> “列表选项” -> “最终列表页模板”,确保它指向了正确的列表页模板文件(通常是
list_article.htm)。
Q2: 我想修改面包屑的分隔符,怎么改?
A:
-
简单方法:直接在模板中用
str_replace函数替换。{dede:field.name='position' runphp='yes'} $position = str_replace(' > ', ' / ', @me); echo $position; {/dede:field}这会把
首页 > 栏目 > 文章变成首页 / 栏目 / 文章。 -
彻底方法:修改
/include/typelink.class.php文件,找到SplitSymbol属性(大约在第 20 行),修改它的值。var $SplitSymbol = ' / '; // 把默认的 ' > ' 改成你想要的
Q3: 面包屑不显示怎么办?
A:
- 确认代码位置:确保
{dede:field name='position'/}或{dede:gettopnav}这段代码已经正确地放在了你的模板文件中。 - 检查缓存:DedeCMS 有模板缓存,修改模板后,请务必在后台“系统” -> “一键更新网站” -> “更新HTML”中更新一下缓存,或者直接删除
/templets/cache/目录下的缓存文件。 - 检查文件权限:确保你的模板文件(如
article_article.htm)是可写的,虽然这很少导致问题,但可以检查一下。
| 需求 | 推荐方法 | 代码示例 |
|---|---|---|
| 标准面包屑 | 方法一 | {dede:field name='position'/} |
| 自定义样式面包屑 | 方法二(修改PHP后) | {dede:gettopnav}<a href='[field:link/]'>[field:name/]</a>{/dede:gettopnav} |
| 修改分隔符 | 模板内替换 | {dede:field.name='position' runphp='yes'}$position = str_replace(' > ', ' / ', @me);echo $position;{/dede:field} |
| 解决层级问题 | 检查栏目设置 | 确保上级栏目类型为“外部链接”或“频道封面”。 |
对于绝大多数用户来说,直接使用 {dede:field name='position'/} 就能满足需求,这是最简单、最稳定的方式。
