第十四篇 Hexo 魔改实录 | 为博客添加一个网站更新日志页面

前言

随着博客的不断更新迭代,我们经常会对网站进行各种优化和改进。为了让读者和自己能够清晰地了解网站的发展历程,添加一个网站更新日志页面是个不错的选择。这样不仅可以记录网站的成长,还能展示我们对博客的用心维护。

本文将详细介绍如何为Hexo博客添加一个美观实用的网站更新日志页面,包括页面创建、数据配置、样式美化等全过程。

实现思路

要实现网站更新日志页面,我们需要完成以下几个步骤:

  1. 创建页面文件和数据文件
  2. 编写页面布局模板
  3. 修改主题配置,添加菜单项
  4. 美化页面样式

下面我们一步步来实现。

创建必要文件

创建页面文件

首先,我们需要创建一个新的页面文件。在博客根目录下执行以下命令:

1
hexo new page changelog

这将在 source/changelog/ 目录下创建一个 index.md 文件。打开该文件,修改其内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
---
title:
date: 2025-08-13 16:31:00
type: changelog
updated: 2025-08-13 16:31:00
comments: true
description: 网站更新日志
keywords: changelog
top_img:
mathjax: false
katex:
aside:
aplayer:
highlight_shrink:
top_single_background:
---

注意,我们将 type 设置为 changelog,这将告诉Hexo使用我们即将创建的自定义布局模板。

创建数据文件

接下来,我们需要创建一个数据文件来存储网站的更新日志信息。在 source/_data/ 目录下创建 changelog.yml 文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
title: 网站更新日志
subtitle:
tip:

changelogs:
- date: 2025-08-12
version: 1.3.8
changes:
- 优化 / 修复 RSS 页面样式
- 更改部分图片
- 更新 隐私协议
- 更新 Cookies 协议
- date: 2025-07-02
version: 1.3.7
changes:
- 微调细节样式
- date: 2025-06-20
version: 1.3.6
changes:
- 微调加载界面
- 捕获安知鱼主题更新
- "fix: 修复即刻短文界面文本换行错误"

在这个文件中,我们定义了页面的标题、副标题和提示信息,以及一个包含多个更新日志条目的数组。每个条目包含日期、版本号和更新内容列表。

创建布局模板

现在,我们需要创建一个布局模板来展示更新日志。在 themes/anzhiyu/layout/includes/page/ 目录下创建 changelog.pug 文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
#article-container
.changelog-container
.changelog-header
h1.changelog-title= site.data.changelog.title
p.changelog-subtitle= site.data.changelog.subtitle
.changelog-tip= site.data.changelog.tip

.changelog-timeline
each item in site.data.changelog.changelogs
.changelog-item
.changelog-item-marker
.changelog-item-content
- var dateObj = new Date(item.date)
- var year = dateObj.getFullYear()
- var month = dateObj.getMonth() + 1
- var day = dateObj.getDate()
- var formattedDate = year + '年' + month + '月' + day + '日'
.changelog-item-date= formattedDate
.changelog-item-version= item.version
.changelog-item-changes
each change in item.changes
.changelog-item-change= change

style.
.changelog-container {
max-width: 900px;
margin: 0 auto;
padding: 40px;
background-color: var(--card-bg);
border-radius: 20px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
}

.changelog-header {
text-align: center;
margin-bottom: 60px;
position: relative;
padding-bottom: 25px;
}

.changelog-header:after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 120px;
height: 5px;
background-image: linear-gradient(to right, #36d1dc 0%, #5b86e5 100%);
border-radius: 3px;
box-shadow: 0 3px 10px rgba(91, 134, 229, 0.3);
}

.changelog-title {
font-size: 3.2rem;
margin-bottom: 20px;
background-image: linear-gradient(to right, #36d1dc 0%, #5b86e5 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-weight: 800;
letter-spacing: 1.5px;
text-shadow: 0 8px 15px rgba(91, 134, 229, 0.2);
}

.changelog-subtitle {
font-size: 1.5rem;
color: var(--font-color);
margin-bottom: 18px;
font-weight: 500;
opacity: 0.85;
}

.changelog-tip {
font-size: 1.2rem;
color: var(--font-color);
margin-bottom: 25px;
font-style: italic;
opacity: 0.7;
}

.changelog-timeline {
position: relative;
padding-left: 45px;
}

.changelog-timeline:before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 6px;
height: 100%;
background-image: linear-gradient(to bottom, #36d1dc 0%, #5b86e5 100%);
border-radius: 3px;
box-shadow: 0 0 25px rgba(91, 134, 229, 0.4);
}

.changelog-item {
position: relative;
margin-bottom: 50px;
animation: fadeInUp 0.6s ease-out both;
animation-delay: calc(var(--i, 0) * 0.15s);
}

.changelog-item-marker {
position: absolute;
left: -48px;
top: 0;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #ff6b6b;
border: 4px solid #fff;
box-shadow: 0 0 0 4px #5b86e5, 0 0 20px rgba(91, 134, 229, 0.6);
transition: all 0.4s ease;
z-index: 1;
}

.changelog-item:hover .changelog-item-marker {
transform: scale(1.3);
background-color: #ff8e8e;
}

.changelog-item-content {
background-color: var(--card-bg);
border-radius: 18px;
padding: 30px;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.08);
transition: all 0.5s cubic-bezier(0.165, 0.84, 0.44, 1);
border: 1px solid rgba(91, 134, 229, 0.15);
position: relative;
overflow: hidden;
}

.changelog-item-content:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 6px;
height: 100%;
background-image: linear-gradient(to bottom, #36d1dc 0%, #5b86e5 100%);
opacity: 0.85;
}

.changelog-item-content:hover {
transform: translateY(-10px) scale(1.02);
box-shadow: 0 20px 40px rgba(91, 134, 229, 0.2);
border-color: rgba(91, 134, 229, 0.4);
}

.changelog-item-date {
font-size: 1.15rem;
color: #36d1dc;
margin-bottom: 10px;
font-weight: 500;
display: inline-block;
padding: 4px 12px;
background-color: rgba(54, 209, 220, 0.12);
border-radius: 20px;
}

.changelog-item-version {
font-size: 1.6rem;
font-weight: bold;
margin-bottom: 18px;
color: var(--font-color);
display: flex;
align-items: center;
}

.changelog-item-version:after {
content: '';
display: inline-block;
width: 60px;
height: 3px;
background-image: linear-gradient(to right, #36d1dc 0%, #5b86e5 100%);
margin-left: 12px;
border-radius: 2px;
}

.changelog-item-changes {
color: var(--font-color);
opacity: 0.9;
}

.changelog-item-change {
margin-bottom: 12px;
position: relative;
padding-left: 28px;
transition: all 0.3s ease;
}

.changelog-item-change:hover {
transform: translateX(8px);
}

.changelog-item-change:before {
content: '•';
position: absolute;
left: 0;
color: #5b86e5;
font-weight: bold;
font-size: 1.6rem;
line-height: 1;
top: -3px;
}

@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

@media (max-width: 768px) {
.changelog-container {
padding: 25px;
margin: 0 15px;
}

.changelog-title {
font-size: 2.4rem;
}

.changelog-subtitle {
font-size: 1.2rem;
}

.changelog-timeline {
padding-left: 35px;
}

.changelog-item-marker {
left: -38px;
width: 16px;
height: 16px;
}

.changelog-item-content {
padding: 22px;
}

.changelog-item-version {
font-size: 1.4rem;
}
}

@media (max-width: 480px) {
.changelog-container {
padding: 20px;
}

.changelog-title {
font-size: 2rem;
}

.changelog-timeline {
padding-left: 30px;
}

.changelog-item-content {
padding: 18px;
}
}

这个模板使用Pug语言编写,定义了更新日志页面的HTML结构和CSS样式。我们创建了一个时间线布局,每个更新日志条目都有日期、版本号和更新内容列表。同时,我们添加了一些动画和交互效果,使页面更加生动。

修改主题配置

接下来,我们需要修改主题的页面布局文件,以支持我们新创建的页面类型。打开 themes/anzhiyu/layout/page.pug 文件,在 case page.type 语句中添加对 changelog 类型的处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
case page.type
when 'tags'
include includes/page/tags.pug
when 'link'
include includes/page/flink.pug
when 'treasure'
include includes/page/treasure.pug
when 'categories'
include includes/page/categories.pug
when 'essay'
include includes/page/essay.pug
when 'room'
include includes/page/room.pug
when 'about'
include includes/page/about.pug
when 'album'
include includes/page/album.pug
when 'fcircle'
include includes/page/fcircle.pug
when 'album_detail'
include includes/page/album_detail.pug
when 'music'
include includes/page/music.pug
when 'equipment'
include includes/page/equipment.pug
when 'dailynote'
include includes/page/dailynote.pug
when 'changelog'
include includes/page/changelog.pug
default
include includes/page/default-page.pug

最后,我们需要在主题配置文件中添加一个菜单项,以便用户可以访问我们的更新日志页面。打开 _config.anzhiyu.yml 文件,在 menu 部分添加以下内容:

1
2
3
4
5
6
7
menu:
# 其他菜单项...
时光:
归档: /archives/ || anzhiyu-icon-box-archive
分类: /categories/ || anzhiyu-icon-shapes
标签: /tags/ || anzhiyu-icon-tags
网站日志: /changelog/ || anzhiyu-icon-clock

这将在"时光"菜单下添加一个"网站日志"菜单项,链接到我们的更新日志页面。

效果展示

完成以上步骤后,我们可以通过以下命令生成并预览网站:

1
hexo clean; hexo g; hexo s

现在,访问 http://localhost:4000/changelog/ 就可以看到我们精心设计的网站更新日志页面了。页面效果如下图所示:

网站更新日志页面效果

可以看到,我们的网站更新日志页面采用了时间线的形式,每个更新条目都有清晰的日期(以"年月日"的格式显示)、版本号和更新内容列表。页面整体风格简洁美观,并且添加了悬停效果和动画,提升了用户体验。

自定义与扩展

你可以根据自己的需求对更新日志页面进行进一步的自定义:

  1. 修改样式:调整 changelog.pug 文件中的CSS样式,改变页面的颜色、字体、动画效果等。

  2. 添加更多信息:在 changelog.yml 文件中添加更多的字段,如重要更新的详细说明、相关链接等。

  3. 增加筛选功能:如果更新日志条目较多,可以添加按版本或日期筛选的功能。

  4. 自定义日期格式:默认情况下,日期会直接显示 changelog.yml 中的原始格式。如果你想要更友好的日期显示格式,可以在 changelog.pug 文件中添加日期格式化代码,例如将 YYYY-MM-DD 格式转换为 YYYY年MM月DD日 格式:

1
2
3
4
5
6
- var dateObj = new Date(item.date)
- var year = dateObj.getFullYear()
- var month = dateObj.getMonth() + 1
- var day = dateObj.getDate()
- var formattedDate = year + '年' + month + '月' + day + '日'
.changelog-item-date= formattedDate

这样,即使在 changelog.yml 中使用 2025-08-12 这样的标准日期格式,在页面上也会显示为 2025年8月12日,更加美观易读。

总结

通过本文的介绍,我们成功地为Hexo博客添加了一个美观实用的网站更新日志页面。这个页面不仅可以记录网站的成长历程,还能展示我们对博客的用心维护,增强用户体验。

实现这个功能主要涉及以下几个步骤:

  1. 创建页面文件和数据文件
  2. 编写页面布局模板
  3. 修改主题配置,添加菜单项
  4. 美化页面样式

希望这篇教程对你有所帮助,让你的博客更加丰富多彩!