使用内置的 {dede:channel} 标签(推荐)
这是最简单、最推荐的方法,适用于大多数场景。{dede:channel} 标签本身就可以通过 typeid 指定栏目,并获取其下的文章数量。

(图片来源网络,侵删)
基本语法
{dede:channel typeid='栏目ID' row='1'}
<a href="[field:typelink/]">[field:typename/]</a> (文章数量: [field:totalpage/])
{/dede:channel}
参数说明
typeid='栏目ID': 必填,指定要调用的栏目的 ID,如果你想在首页调用所有顶级栏目,可以省略此参数。row='数量': 可选,表示获取多少个栏目,这里我们只调用一个,所以设为1。type='top': 可选,表示只调用顶级栏目,在首页调用所有顶级栏目时常用。currentstyle: 可选,用于为当前栏目所在的链接应用特定的样式。
字段说明
[field:typelink/]: 栏目的链接地址。[field:typename/]: 栏目的名称。[field:totalpage/]: 这个就是关键,它表示该栏目下的文章总数(分页数)。
场景示例
示例 1:在首页调用所有顶级栏目及其文章数量
这是最常用的场景,通常用于网站的侧边栏或底部导航。
<h3>网站栏目</h3>
<ul>
{dede:channel type='top' row='8'}
<li>
<a href="[field:typelink/]">[field:typename/]</a>
<span>([field:totalpage/])</span>
</li>
{/dede:channel}
</ul>
效果示例:
新闻中心”栏目 ID 为 1,下面有 25 篇文章,那么渲染出来的 HTML 可能是:
<li><a href="/news/">新闻中心</a><span>(25)</span></li>
示例 2:在列表页调用当前栏目及其子栏目的文章数量
在某个列表页(/news/list_1.html),你可能想显示“新闻中心”本身和它的子栏目(如“国内新闻”、“国际新闻”)的文章数量。
<h2>当前位置:{dede:field name='typename'/}</h2>
<p>本栏目共有 [field:totalpage/] 篇文章。</p>
<h3>子栏目</h3>
<ul>
{dede:channel typeid='当前栏目ID' noself='yes'}
<li>
<a href="[field:typelink/]">[field:typename/]</a>
<span>([field:totalpage/])</span>
</li>
{/dede:channel}
</ul>
typeid='当前栏目ID': 在列表页,可以使用{dede:field name='typeid'/}来获取当前栏目的 ID,所以完整的写法是typeid='{dede:field name='typeid'/}'。noself='yes': 表示不调用栏目本身,只调用其子栏目。
使用自定义 {dede:sql}
当 {dede:channel} 标签无法满足复杂需求时(需要根据特定条件筛选文章来计数),可以使用 {dede:sql} 标签直接执行 SQL 查询,这种方法更灵活,但对 SQL 语句有一定要求。
(图片来源网络,侵删)
基本语法
{dede:sql sql="SELECT COUNT(*) as total FROM `dede_archives` WHERE typeid = 栏目ID"}
该栏目共有 [field:total/] 篇文章。
{/dede:sql}
参数说明
sql="SELECT ...": 必填,你的 SQL 查询语句。
[field:别名/]: 在 SQL 语句中,你可以使用 AS 关键字为查询结果指定一个别名,然后在模板中通过 [field:别名/] 来调用。
SQL 语句详解
dede_archives: 这是 DedeCMS 存储文章核心信息的表,包括文章 ID、标题、所属栏目 ID 等。
- *`COUNT()`**: 这是 SQL 的聚合函数,用于计算满足条件的记录总数。
WHERE typeid = 栏目ID: 这是筛选条件,只计算指定栏目 ID 的文章。
场景示例
示例 1:调用指定栏目(ID=1)的文章数量
{dede:sql sql="SELECT COUNT(*) as total FROM `dede_archives` WHERE typeid=1"}
新闻中心栏目共有 [field:total/] 篇文章。
{/dede:sql}
示例 2:调用当前栏目的文章数量(在列表页使用)
{dede:sql sql="SELECT COUNT(*) as total FROM `dede_archives` WHERE typeid=~typeid~"}
当前栏目共有 [field:total/] 篇文章。
{/dede:sql}
~typeid~: 这是 DedeCMS 模板引擎提供的特殊变量,它会自动被替换为当前页面的栏目 ID,非常方便!
示例 3:调用指定栏目及其所有子栏目的文章数量(递归查询)
这是一个稍微复杂但非常实用的需求,新闻中心”(ID=1)下面有“国内新闻”(ID=2)和“国际新闻”(ID=3),我们想统计 1, 2, 3 这三个栏目的所有文章总数。
DedeCMS 的 dede_arctype 表中有一个 reid 字段,表示父栏目的 ID,我们可以利用这个来构建查询。
{dede:sql sql="SELECT COUNT(*) as total FROM `dede_archives` WHERE typeid IN (1, 2, 3)"}
新闻中心及其子栏目共有 [field:total/] 篇文章。
{/dede:sql}
但是手动写 (1, 2, 3) 很不方便,我们可以先查询出所有子栏目的 ID,再拼接到主查询中,虽然 {dede:sql} 不支持嵌套,但我们可以利用 DedeCMS 的变量机制。
更优化的写法(推荐):
在需要调用的地方,先执行一个查询来获取 ID 列表,再使用它。
{dede:sql sql="SELECT GROUP_CONCAT(id) as ids FROM `dede_arctype` WHERE id=1 OR reid=1"}
{dede:sql sql="SELECT COUNT(*) as total FROM `dede_archives` WHERE typeid IN ([field:ids/])"}
新闻中心及其子栏目共有 [field:total/] 篇文章。
{/dede:sql}
{/dede:sql}
GROUP_CONCAT(id): 将查询出的所有 ID(如 1, 2, 3)拼接成一个逗号分隔的字符串。
WHERE id=1 OR reid=1: 这个条件会找到 ID 为 1 的栏目本身,以及所有父栏目 ID 为 1 的子栏目。
[field:ids/]: 将第一个查询得到的 ID 字符串传递给第二个查询。
总结与对比
特性
{dede:channel}
{dede:sql}
易用性
非常简单,无需写 SQL
需要了解基本的 SQL 语法
性能
性能更好,系统已经做了优化
性能取决于 SQL 语句的复杂度,复杂查询可能较慢
灵活性
较低,只能获取栏目固有的信息
极高,可以任意组合查询条件
适用场景
大多数常规需求,如显示栏目列表和文章数
复杂统计、跨表查询、自定义条件筛选
- 如果只是想显示栏目和它下面的文章总数,请优先使用
{dede:channel},它是为此而生的,最简单、最高效。
- 如果需要根据文章状态(如仅审核通过的)、发布时间、或其他复杂条件来统计文章数量,那么请使用
{dede:sql},它能给你最大的自由度。
当 {dede:channel} 标签无法满足复杂需求时(需要根据特定条件筛选文章来计数),可以使用 {dede:sql} 标签直接执行 SQL 查询,这种方法更灵活,但对 SQL 语句有一定要求。

(图片来源网络,侵删)
基本语法
{dede:sql sql="SELECT COUNT(*) as total FROM `dede_archives` WHERE typeid = 栏目ID"}
该栏目共有 [field:total/] 篇文章。
{/dede:sql}
参数说明
sql="SELECT ...": 必填,你的 SQL 查询语句。[field:别名/]: 在 SQL 语句中,你可以使用AS关键字为查询结果指定一个别名,然后在模板中通过[field:别名/]来调用。
SQL 语句详解
dede_archives: 这是 DedeCMS 存储文章核心信息的表,包括文章 ID、标题、所属栏目 ID 等。- *`COUNT()`**: 这是 SQL 的聚合函数,用于计算满足条件的记录总数。
WHERE typeid = 栏目ID: 这是筛选条件,只计算指定栏目 ID 的文章。
场景示例
示例 1:调用指定栏目(ID=1)的文章数量
{dede:sql sql="SELECT COUNT(*) as total FROM `dede_archives` WHERE typeid=1"}
新闻中心栏目共有 [field:total/] 篇文章。
{/dede:sql}
示例 2:调用当前栏目的文章数量(在列表页使用)
{dede:sql sql="SELECT COUNT(*) as total FROM `dede_archives` WHERE typeid=~typeid~"}
当前栏目共有 [field:total/] 篇文章。
{/dede:sql}
~typeid~: 这是 DedeCMS 模板引擎提供的特殊变量,它会自动被替换为当前页面的栏目 ID,非常方便!
示例 3:调用指定栏目及其所有子栏目的文章数量(递归查询)
这是一个稍微复杂但非常实用的需求,新闻中心”(ID=1)下面有“国内新闻”(ID=2)和“国际新闻”(ID=3),我们想统计 1, 2, 3 这三个栏目的所有文章总数。
DedeCMS 的 dede_arctype 表中有一个 reid 字段,表示父栏目的 ID,我们可以利用这个来构建查询。
{dede:sql sql="SELECT COUNT(*) as total FROM `dede_archives` WHERE typeid IN (1, 2, 3)"}
新闻中心及其子栏目共有 [field:total/] 篇文章。
{/dede:sql}
但是手动写 (1, 2, 3) 很不方便,我们可以先查询出所有子栏目的 ID,再拼接到主查询中,虽然 {dede:sql} 不支持嵌套,但我们可以利用 DedeCMS 的变量机制。
更优化的写法(推荐):
在需要调用的地方,先执行一个查询来获取 ID 列表,再使用它。
{dede:sql sql="SELECT GROUP_CONCAT(id) as ids FROM `dede_arctype` WHERE id=1 OR reid=1"}
{dede:sql sql="SELECT COUNT(*) as total FROM `dede_archives` WHERE typeid IN ([field:ids/])"}
新闻中心及其子栏目共有 [field:total/] 篇文章。
{/dede:sql}
{/dede:sql}
GROUP_CONCAT(id): 将查询出的所有 ID(如 1, 2, 3)拼接成一个逗号分隔的字符串。WHERE id=1 OR reid=1: 这个条件会找到 ID 为 1 的栏目本身,以及所有父栏目 ID 为 1 的子栏目。[field:ids/]: 将第一个查询得到的 ID 字符串传递给第二个查询。
总结与对比
| 特性 | {dede:channel}
| |
|---|---|---|
| 易用性 | 非常简单,无需写 SQL | 需要了解基本的 SQL 语法 |
| 性能 | 性能更好,系统已经做了优化 | 性能取决于 SQL 语句的复杂度,复杂查询可能较慢 |
| 灵活性 | 较低,只能获取栏目固有的信息 | 极高,可以任意组合查询条件 |
| 适用场景 | 大多数常规需求,如显示栏目列表和文章数 | 复杂统计、跨表查询、自定义条件筛选 |
- 如果只是想显示栏目和它下面的文章总数,请优先使用
{dede:channel},它是为此而生的,最简单、最高效。 - 如果需要根据文章状态(如仅审核通过的)、发布时间、或其他复杂条件来统计文章数量,那么请使用
{dede:sql},它能给你最大的自由度。
