dede_tagindex 标签本身不直接接收一个 typeid(栏目ID)参数来筛选指定栏目的标签,它的设计初衷是获取全站的热门标签。

通过结合其他方法和一些“技巧”,我们完全可以实现“获取指定栏目下的热门标签”这个功能,下面我将从基础到高级,为你详细解释。
dede_tagindex 标签基础
我们来看看 dede_tagindex 标签的基本用法和参数。
标签作用
用于获取全站所有标签中被引用次数最多(即最热门)的标签列表,通常用于网站首页的侧边栏或页脚,展示站点的核心关键词。
基本语法
{dede:tagindex}
<a href='[field:link/]'>[field:tagname/]</a>
{/dede:tagindex}
常用参数
| 参数 | 说明 | 示例 |
|---|---|---|
row |
获取标签的数量(必填) | row='20' 表示获取前20个热门标签 |
getall |
是否获取所有标签,而不仅仅是热门标签 | getall='0' (默认,获取热门) getall='1' (获取所有,row 参数可能失效) |
sort |
排序方式 | sort='month' (按月统计) sort='week' (按周统计) sort='rand' (随机获取) |
length |
标签名称显示的最大长度 | length='6' (如果标签名超过6个字符,则截断) |
示例:获取全站前15个热门标签,按月统计,标签名最长显示8个字符。

{dede:tagindex row='15' sort='month' length='8'}
<li><a href='[field:link/]'>[field:tagname/]</a></li>
{/dede:tagindex}
如何实现“按栏目ID获取标签”?
这是你问题的核心,由于 dede_tagindex 本身不支持 typeid,我们需要采用以下几种方法:
修改PHP源码(最直接,但需要技术能力)
这是最根本的解决方案,直接在标签底层代码中加入栏目筛选逻辑。
-
找到文件: 打开
/include/taglib/tagindex.lib.php文件。 -
修改代码: 在这个文件中,你会找到一段执行SQL查询的代码,原始代码大致如下(版本不同可能略有差异):
(图片来源网络,侵删)// 原始代码片段 $dsql->SetQuery("SELECT tagname,count FROM `dede_tagindex` ORDER BY count DESC LIMIT 0,$row"); $dsql->Execute('al'); -
增加栏目筛选逻辑: 我们需要修改这个SQL查询,让它只统计属于特定栏目(或其子栏目)的文档的标签。
// 修改后的代码示例 (假设我们要增加 typeid 参数) global $typeid; // 构建子栏目ID列表 $typeid = isset($typeid) && is_numeric($typeid) ? $typeid : 0; $typeid_arr = array(); if($typeid > 0) { // 获取当前栏目及其所有子栏目的ID $typeid_arr = GetSonIds($typeid); $typeid_arr[] = $typeid; // 把自己也加进去 $typeid_str = join(',', $typeid_arr); $addsql = " AND arc.typeid IN ($typeid_str)"; } else { $addsql = ''; } // 修改SQL查询,通过 dede_taglist 表关联,并筛选栏目 $dsql->SetQuery("SELECT t.tagname, t.count FROM `dede_tagindex` t LEFT JOIN `dede_taglist` tl ON t.tagname = tl.tag LEFT JOIN `dede_archives` arc ON tl.aid = arc.id WHERE 1=1 $addsql GROUP BY t.tagname ORDER BY t.count DESC LIMIT 0,$row"); $dsql->Execute('al'); -
使用标签: 修改后,你就可以在模板中这样使用了:
{dede:tagindex typeid='' row='10'} <a href='[field:link/]'>[field:tagname/]</a> {/dede:tagindex}注意:
typeid参数需要你通过其他方式传递进来,例如在栏目页模板中,可以使用typeid这个全局变量。
优点:功能最强大,效率最高。 缺点:需要修改核心文件,升级DedeCMS时可能会被覆盖,需要重新修改。
使用SQL直接查询(灵活,适合高级用户)
如果你不想修改PHP文件,可以在模板文件中使用 {dede:sql} 标签直接执行自定义的SQL查询。
思路:
- 从
dede_taglist表中找出所有属于指定栏目(typeid)的文档的标签。 - 统计每个标签出现的次数。
- 按次数排序,取前N个。
示例:获取栏目ID为 '1' 的热门标签前10个
{dede:sql sql="
SELECT tl.tag, COUNT(tl.aid) as count
FROM `dede_taglist` tl
LEFT JOIN `dede_archives` arc ON tl.aid = arc.id
WHERE arc.typeid IN (1)
GROUP BY tl.tag
ORDER BY count DESC
LIMIT 0,10
"}
<a href='/tags.php?/[field:tag/]/'>[field:tag/] ([field:count/])</a>
{/dede:sql}
如何获取子栏目?
如果你需要包含栏目1的所有子栏目,你需要先手动获取子栏目ID列表,然后替换SQL中的 IN (1)。
如果栏目ID为1的子栏目有 3, 4, 5,那么SQL就写成 WHERE arc.typeid IN (1,3,4,5)。
优点:
- 无需修改核心文件,安全。
- 灵活性极高,可以写任意复杂的SQL。
缺点:
- 每次页面加载都会执行一次SQL,如果标签数据量大,可能会对性能有一定影响。
- 需要手动处理子栏目ID,不够自动化。
通过二次开发(推荐)
这是最规范、最推荐的方法,尤其对于需要长期维护的网站。
-
创建自定义标签函数: 在
/include/taglib/目录下新建一个文件,mytag.lib.php。 -
编写函数: 在
mytag.lib.php中编写一个自定义的标签解析函数。<?php if(!defined('DEDEINC')) exit('Request Error!'); function lib_mytag(&$ctag, &$refObj) { global $dsql; // 获取标签属性 $typeid = $ctag->GetAtt('typeid'); $row = $ctag->GetAtt('row', '20'); // 默认20条 // 如果没有typeid,直接返回空 if(empty($typeid)) { return ''; } // 获取子栏目ID $typeid_arr = GetSonIds($typeid); $typeid_arr[] = $typeid; $typeid_str = join(',', $typeid_arr); // 执行查询 $sql = "SELECT t.tagname, t.count FROM `dede_tagindex` t LEFT JOIN `dede_taglist` tl ON t.tagname = tl.tag LEFT JOIN `dede_archives` arc ON tl.aid = arc.id WHERE arc.typeid IN ($typeid_str) GROUP BY t.tagname ORDER BY t.count DESC LIMIT 0,{$row}"; $dsql->SetQuery($sql); $dsql->Execute('mytag'); $ctp = new DedeTagParse(); $ctp->SetNameSpace('field', '[', ']'); $ctp->LoadSource($ctag->GetInnerText()); $artlist = ''; while($row = $dsql->GetArray('mytag')) { foreach($ctp->CTags as $tagid=>$ctag) { $ctp->Assign($tagid, $row[$ctag->GetName()]); } $artlist .= $ctp->GetResult(); } return $artlist; } ?> -
在模板中使用: 现在你就可以在任意模板中像使用普通标签一样使用它了。
{dede:mytag typeid='1' row='10'} <a href='[field:link/]'>[field:tagname/]</a> {/dede:mytag}注意:这里的
[field:link/]和[field:tagname/]需要在你的mytag.lib.php中处理并赋值,或者直接在模板里写死链接,如href='/tags.php?/[field:tagname/]/'。
优点:
- 代码整洁,不污染核心文件。
- 可复用性强,可以在任何地方调用。
- 符合DedeCMS的二次开发规范。
缺点:
- 需要一定的PHP和DedeCMS二次开发基础。
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 修改源码 | 功能强大,效率高 | 升级麻烦,有风险 | 对性能要求极高,且不担心升级的私有项目 |
| SQL直接查询 | 无需修改文件,灵活 | 性能稍差,子栏目处理麻烦 | 临时需求,或对性能要求不高的页面 |
| 二次开发 | 规范,可复用,安全 | 需要开发基础 | 长期维护的网站,推荐使用 |
对于大多数用户来说,方法三(二次开发)是最佳选择,它既解决了问题,又保持了代码的整洁和可维护性,如果你只是临时需要一个效果,方法二(SQL直接查询)也是一个不错的折中方案。
