dede如何统计每个栏目的文章数量?

99ANYc3cd6
预计阅读时长 19 分钟
位置: 首页 DEDE建站 正文

使用 GetSonids 标签(推荐,适用于子栏目)

这是最常用且最灵活的方法,它利用了 DedeCMS 的标签系统,可以在模板中直接调用,它的核心原理是先获取当前栏目的所有子栏目 ID(包括孙栏目等),然后再统计这些 ID 下的文章总数。

dede 统计各个栏目下文章数量
(图片来源网络,侵删)

适用场景:在列表页或首页,显示某个顶级栏目及其所有子栏目的文章总数。

示例代码:

假设你的顶级栏目 ID 是 1(新闻中心”),你可以在模板中这样写:

{dede:channel type='top' typeid='1'}
    <dl>
        <dt><a href="[field:typeurl/]">[field:typename/]</a></dt>
        <dd>
            <!-- 使用 GetSonids 标签获取所有子栏目ID,并用逗号隔开 -->
            {dede:getsonids typeid='1' noself='yes'}
                [field:id function="GetSonIds(@me,0)"/],
            {/dede:getsonids}
            <!-- 获取上一步生成的所有子栏目ID,并统计文章数 -->
            {dede:arclist sort='hot' channelid='1' subday='30' titlelen='42' 
                         row='1' idlist=''}
                总文章数:[field:total/]
            {/dede:arclist}
        </dd>
    </dl>
{/dede:channel}

代码解释:

dede 统计各个栏目下文章数量
(图片来源网络,侵删)
  1. {dede:channel type='top' typeid='1'}: 调用顶级栏目,这里指定了栏目ID为 1
  2. {dede:getsonids typeid='1' noself='yes'}: 这个标签本身不输出内容,它的作用是在底层生成一个包含所有子栏目ID的变量,格式如 2,3,4,
  3. [field:id function="GetSonIds(@me,0)"/]: 这是调用一个自定义函数 GetSonIds,它会递归获取指定ID的所有子栏目ID。@me 是当前栏目ID(这里是1),0 表示不包含自己,它会生成一个ID字符串,如 2,3,4,
  4. {dede:arclist ... idlist='...'}: arclist 标签有一个 idlist 属性,可以指定只查询这些ID栏目下的文章,我们将上一步生成的ID字符串赋给它。
  5. [field:total/]: 这是 arclist 标签的一个特殊字段,表示 idlist 中所有栏目的文章总数。

更简洁的写法(推荐):

DedeCMS 的 arclist 标签本身支持 typeid 属性接受一个由逗号隔开的ID字符串,所以可以更简洁:

{dede:channel type='top' typeid='1'}
    <h2>[field:typename/]</h2>
    <p>
        {dede:getsonids typeid='1' noself='yes'}
            [field:id function="GetSonIds(@me,0)"/],
        {/dede:getsonids}
        <!-- 直接使用生成的ID列表 -->
        {dede:arclist row='0' idlist=''}
            本栏目及其子栏目共有 [field:total/] 篇文章。
        {/dede:arclist}
    </p>
{/dede:channel}

注意:这里 idlist 是空的,它会自动使用 {dede:getsonids} 在底层生成的变量。


使用 SQL 查询标签(最灵活,适用于所有情况)

如果方法一不能满足你的需求,或者你想进行更复杂的统计(比如按特定条件筛选),可以直接使用 DedeCMS 的 dede:sql 标签执行原生 SQL 查询。

适用场景:需要精确控制查询条件,或者统计方法一无法覆盖到的复杂情况。

示例1:统计单个栏目及其所有子栏目的文章数

假设顶级栏目ID为 1

{dede:sql sql="
    SELECT COUNT(*) as total 
    FROM `#@__archives` 
    WHERE typeid IN (
        SELECT id FROM `#@__arctype` 
        WHERE reid = 1 OR topid = 1
    )
"}
    本栏目及其子栏目共有 [field:total/] 篇文章。
{/dede:sql}

SQL 语句解释:

  • SELECT COUNT(*) as total FROM dede_archives: 统计 dede_archives (文章表) 中的记录数,并将结果命名为 total
  • WHERE typeid IN (...): 只统计 typeid (栏目ID) 在括号列表中的文章。
  • SELECT id FROM dede_arctype WHERE reid = 1 OR topid = 1: 这是一个子查询,它从 dede_arctype (栏目表) 中找出所有父级ID (reid) 是 1 或者顶级ID (topid) 是 1 的栏目ID,这样就获取了栏目 1 的所有直接和间接子栏目。

示例2:统计所有顶级栏目及其子栏目的文章数

这个需求更常见,比如在首页做一个网站地图。

<ul>
    {dede:channel type='top'}
        <li>
            <strong>[field:typename/]</strong>
            <!-- 对每个顶级栏目,执行一次SQL查询 -->
            {dede:sql sql="
                SELECT COUNT(*) as total 
                FROM `#@__archives` 
                WHERE typeid IN (
                    SELECT id FROM `#@__arctype` WHERE reid = ~typeid~
                )
            "}
                ([field:total/])
            {/dede:sql}
            <!-- 递归调用自身,显示子栏目 -->
            {dede:channel type='son' noself='yes'}
                - [field:typename/]
            {/dede:channel}
        </li>
    {/dede:channel}
</ul>

注意:这里的 ~typeid~ 是一个占位符,DedeCMS 会自动将其替换为当前循环的栏目的 typeid 值。


使用自定义函数(性能最高,适合高级用户)

如果你的网站对性能要求极高,并且这个功能在多个地方被频繁调用,可以考虑创建一个自定义函数,然后在模板中调用,这需要你修改 PHP 文件。

步骤:

  1. 创建函数文件: 在 /include/extend.func.php 文件中(如果不存在则创建一个)添加以下函数:

    /**
     * 统计指定栏目及其所有子栏目的文章数量
     * @param int $typeid 栏目ID
     * @return int 文章总数
     */
    function GetTotalArticles($typeid = 0) {
        if ($typeid == 0) return 0;
        global $dsql;
        // 获取所有子栏目ID
        $sonids = GetSonIds($typeid, 0);
        $idstring = empty($sonids) ? $typeid : $typeid . ',' . $sonids;
        // 执行查询
        $query = "SELECT COUNT(*) FROM `#@__archives` WHERE typeid IN ($idstring)";
        $total = $dsql->GetOne($query);
        return $total['COUNT(*)'];
    }
  2. 在模板中调用: 在任何需要的地方,通过 [field:function] 标签调用。

    {dede:channel type='top' typeid='1'}
        [field:typename/]:[field:function='GetTotalArticles(@me)'/] 篇文章
    {/dede:channel}

    或者

    当前栏目 [field:typename/] 的文章数是:[field:function='GetTotalArticles(@me)'/]

优点

  • 性能最好:函数直接执行数据库查询,没有模板解析的额外开销。
  • 代码复用:定义一次,处处可用。
  • 逻辑清晰:将数据库操作与模板分离。

缺点

  • 需要修改 PHP 文件,对新手有一定门槛。

总结与建议

方法 优点 缺点 推荐场景
GetSonids 纯模板实现,无需修改代码,灵活性好 在循环内使用时,效率不如方法三 大多数日常需求,如列表页、首页的栏目统计。
dede:sql 灵活性最强,可处理复杂查询 SQL 语句相对复杂,可读性稍差 需要特殊筛选条件或方法一无法满足时。
自定义函数 性能最高,代码复用性好 需要修改PHP文件,不适合新手 对性能要求极高的网站,或该功能被高频调用时。

对于绝大多数用户,方法一 是最简单、最直接、最安全的选择,如果遇到性能瓶颈或特殊需求,再考虑 方法二方法三

-- 展开阅读全文 --
头像
C/C++同为编译型,区别在哪儿?
« 上一篇 2025-12-21
dede如何调用分类文章并限制显示字数?
下一篇 » 2025-12-21
取消
微信二维码
支付宝二维码

目录[+]