Lumin Blog 文章字数与阅读时长功能文档
📌 概述
Lumin Blog 利用 Hugo 内置的 .WordCount 和 .ReadingTime 变量,在文章详情页、首页卡片和分类列表页三个位置展示文章的字数统计和预计阅读时长,帮助读者快速判断文章篇幅。
🎯 一、功能说明
1.1 显示位置与内容
| 位置 | 显示内容 | 示例 |
|---|---|---|
| 文章详情页 | 阅读时长 · 字数 | 3 分钟 · 1200 字 |
| 首页卡片 | 阅读时长 · 字数 | 3 分钟 · 1200 字 |
| 分类列表页 | 阅读时长 · 字数 | 3 分钟 · 1200 字 |
1.2 图标
所有位置统一使用时钟图标(🕐)标识,与日期的日历图标形成视觉区分:
1📅 2026-05-21 🕐 3 分钟 · 1200 字 📁 技术 🏷️ #Hugo
🏗️ 二、技术实现
2.1 Hugo 内置变量
Hugo 在构建时自动为每个页面计算两个变量:
| 变量 | 类型 | 说明 |
|---|---|---|
.WordCount | 整数 | 文章的字数统计。启用 hasCJKLanguage 后,中文每个字计为 1 |
.ReadingTime | 整数 | 预计阅读时长(分钟)。启用 hasCJKLanguage 后按 300 字/分钟计算 |
2.2 中文阅读速度优化
关键配置:hugo.toml 中的 hasCJKLanguage = true
1hasCJKLanguage = true # 启用 CJK 检测,阅读时长按中文计算
作用对比:
| 配置 | 阅读速度 | 1500 字中文文章 | 说明 |
|---|---|---|---|
hasCJKLanguage = false(默认) | 200 词/分钟 | 显示 8 分钟 | 按英文计算,偏多 |
hasCJKLanguage = true | 300 字/分钟 | 显示 5 分钟 | 按中文计算,更准确 |
原理:Hugo 默认按英文阅读速度(200 词/分钟)计算 .ReadingTime。中文没有"词"的概念,每个汉字被当作一个词,导致计算结果偏大。启用 hasCJKLanguage 后,Hugo 会检测内容中的 CJK 字符,改用 300 字/分钟计算。
2.3 文章详情页实现
定义在 layouts/_default/single.html 中,字数和阅读时长合并为一个 meta-item:
1{{ if or site.Params.article.showWordCount site.Params.article.showReadingTime }}
2<span class="meta-item">
3 <svg ...>🕐时钟图标</svg>
4 {{ if site.Params.article.showReadingTime }}
5 {{ .ReadingTime }} 分钟
6 {{ end }}
7 {{ if and site.Params.article.showWordCount site.Params.article.showReadingTime }}
8 ·
9 {{ end }}
10 {{ if site.Params.article.showWordCount }}
11 {{ .WordCount }} 字
12 {{ end }}
13</span>
14{{ end }}
设计要点:
- 字数和阅读时长合并为一个 meta-item,共用一个图标,节省水平空间
- 两个功能独立开关,可单独启用/关闭
- 同时启用时用
·分隔,如3 分钟 · 1200 字 - 仅启用字数时显示
1200 字,仅启用阅读时长时显示3 分钟
2.4 首页卡片实现
定义在 layouts/index.html 中,位于日期和分类之间:
1<span class="meta-item meta-reading">
2 <svg ...>🕐时钟图标</svg>
3 {{ .ReadingTime }} 分钟 · {{ .WordCount }} 字
4</span>
首页卡片始终显示阅读时长和字数,不受配置开关控制(因为首页信息密度高,字数是核心参考信息)。
2.5 分类列表页实现
定义在 layouts/partials/archive-post-list.html 中:
1{{ with $pg.ReadingTime }}
2<span class="term-item-meta">
3 <svg ...>🕐时钟图标</svg>
4 {{ . }} 分钟 · {{ $pg.WordCount }} 字
5</span>
6{{ end }}
使用 {{ with }} 包裹,当 .ReadingTime 为 0 时(极少见)自动隐藏整个 meta。
⚙️ 三、配置方法
3.1 全局开关
在 hugo.toml 的 [params.article] 中控制文章详情页的显示:
1[params.article]
2 showWordCount = true # 显示字数统计
3 showReadingTime = true # 显示阅读时间
| showWordCount | showReadingTime | 文章详情页显示 |
|---|---|---|
| true | true | 3 分钟 · 1200 字 |
| true | false | 1200 字 |
| false | true | 3 分钟 |
| false | false | 不显示 |
3.2 CJK 语言检测
1hasCJKLanguage = true # 必须设置,否则阅读时长按英文计算
此配置为 Hugo 顶级设置,影响全局的 .WordCount 和 .ReadingTime 计算。
3.3 首页和列表页
首页卡片和分类列表页的阅读时长+字数始终显示,无独立开关。如需隐藏,需修改对应模板文件。
🔍 四、计算规则详解
4.1 字数统计(.WordCount)
Hugo 的字数统计规则:
| 语言类型 | 计算方式 | 示例 |
|---|---|---|
| 英文 | 按空格分词计数 | “Hello World” = 2 词 |
| 中文(启用 CJK) | 每个汉字计为 1 | “你好世界” = 4 字 |
| 混合内容 | 分别计算后相加 | “Hello你好” = 1 + 2 = 3 |
注意:.WordCount 统计的是正文内容,不包含标题、Front Matter、短代码等。
4.2 阅读时长(.ReadingTime)
1阅读时长(分钟)= 字数 / 阅读速度
2
3英文模式:ReadingTime = WordCount / 200
4CJK 模式:ReadingTime = WordCount / 300
结果向下取整,最小值为 0。对于极短文章(< 300 字),显示 0 分钟。
4.3 “0 分钟"问题
对于短文章(如公告、碎碎念),.ReadingTime 可能返回 0,显示为 0 分钟。这在视觉上不太友好。
可选优化方案(如需修改):
在模板中将 0 替换为 1:
1{{ $rt := .ReadingTime }}
2{{ if eq $rt 0 }}{{ $rt = 1 }}{{ end }}
3{{ $rt }} 分钟
📊 五、各页面显示对比
5.1 优化前后对比
| 页面 | 优化前 | 优化后 |
|---|---|---|
| 文章详情页 | 两个 meta-item,各一个图标 | 一个 meta-item,一个图标 |
| 首页卡片 | 无字数和阅读时长 | ✅ 显示 X 分钟 · X 字 |
| 分类列表页 | 仅显示 X 分钟 | ✅ 显示 X 分钟 · X 字 |
5.2 信息层级
1文章详情页(完整信息)
2├── 🕐 3 分钟 · 1200 字
3├── 👁️ 128 阅读
4└── 💬 5 评论
5
6首页卡片(摘要信息)
7├── 📅 2026-05-21
8├── 🕐 3 分钟 · 1200 字 ← 新增
9├── 📁 技术
10└── 🏷️ #Hugo
11
12分类列表页(紧凑信息)
13├── 📅 2026-05-21
14└── 🕐 3 分钟 · 1200 字 ← 补充字数
📁 六、相关文件索引
| 文件 | 作用 |
|---|---|
layouts/_default/single.html L78-83 | 文章详情页字数+阅读时长显示 |
layouts/index.html L74-77 | 首页卡片字数+阅读时长显示 |
layouts/partials/archive-post-list.html L22-27 | 分类列表页字数+阅读时长显示 |
hugo.tom L32 hasCJKLanguage | CJK 语言检测开关 |
hugo.toml L514-515 showWordCount/showReadingTime | 文章详情页显示开关 |
🐛 七、常见问题
Q1: 为什么阅读时长和实际阅读速度不一致?
Hugo 的 .ReadingTime 是基于字数的估算,实际阅读速度因人而异。技术文章通常需要反复理解代码和概念,实际阅读时间可能是估算的 2-3 倍。这是所有博客系统的通用局限。
Q2: 首页卡片的字数统计包含图片 alt 文字吗?
不包含。.WordCount 仅统计正文纯文本,图片的 alt 属性、HTML 标签属性等不计入。
Q3: 如何修改阅读速度基准?
Hugo 不支持自定义阅读速度。hasCJKLanguage 只提供两档:200 词/分钟(英文)和 300 字/分钟(CJK)。如需更精确的计算,可以在模板中用 .WordCount 自行计算:
1{{ $minutes := div .WordCount 250 }}
2{{ if eq $minutes 0 }}{{ $minutes = 1 }}{{ end }}
3约 {{ $minutes }} 分钟
留言评论
期待你的想法评论加载中