网站搭建

网站搭建
小米里的大麦同款博客搭建
声明:本篇文章是介绍安知鱼博客网站的搭建及其魔改,对待 0 基础的朋友比较不友好,但你仍然可以凭借好的学习能力和借助 B 站、AI、百度等完成个人网站的搭建!如有不懂可在文章下方评论区评论,我会尽力解答……
1. hexo 和 安知鱼主题的安装
前提必备技能:GitHub 仓库的基本使用以及 VS Code 的基本使用!
环境与工具准备(最好可以稳定连接 GitHub)
Node.js — Download Node.js®(这里选用
v18.17.1
到22.16.0
版本兼容性较好,请确保勾选 Add to PATH 选项(默认已勾选))- 安装完成后,检查是否安装成功。在键盘按下 win + R 键,输入 CMD,然后回车,打开 CMD 窗口,执行
node -v
命令,看到版本信息,则说明安装成功。
- 安装完成后,检查是否安装成功。在键盘按下 win + R 键,输入 CMD,然后回车,打开 CMD 窗口,执行
文本编辑器:VS Code 下载(推荐) 或者 Trae - AI 原生 IDE 下载(看个人,选任意一个或者都选都可以)
- 后续的
hexo cl;hexo g;hexo s
命令可能执行会出问题,解决方法:使用管理员身份运行 VS Code 以及 vscode 不能在终端执行程序脚本 | CSDN 或者 在 windows 下 vscode 终端里无法运行脚本解决方案 | CSDN 博客 或者 在 VS Code 命令面板,输入并选择:Terminal: Select Default Profile
(三种选择任意一种即可,出错自行 AI/百度)
- 后续的
安装 Hexo
在终端(CMD)中输入:
1
npm install -g hexo-cli
安装完后输入 hexo -v 验证是否安装成功。
在 GitHub 上创建一个仓库,注意名称格式必须是 你的用户名.github.io !
初始化 Hexo 项目
找到一个存放博客的地方(文件夹要是空的),输入命令:
1
hexo init MyBlog # MyBlog是项目名,也是文件夹的名称,这里自己自定义即可
完成后,在这个文件夹里就可以看到下面的内容:
安装 hexo-deployer-git(将静态博客挂载到 GitHub Pages,直观来说就是将本地博客状态推送至 GitHub)
安装
1
npm install hexo-deployer-git --save
修改
_config.yml
文件:修改最后一行的配置,将 repository 修改为你自己的 github 项目地址即可,还有分支要改为main
代表主分支(注意缩进)。1
2
3
4deploy:
type: git
repository: git@github.com:你的GitHub用户名.github.io.git # 也可以https://github.com/你的用户名.github.io.git
branch: main推送命令(注意推送前最好使用先使用
hexo cl;hexo g;hexo s
,确保最新且没问题):1
hexo deployer # 我们常用简写 hexo d
当我们完成第一次推送(
hexo d
)后,正常来说就可以通过 GitHub 自动分配的 你的 GitHub 用户名 github.io 的这个域名进行网站的访问了(可能存在几分钟的延迟)。
主题安装和博客搭建(安知鱼主题官方文档)
下面使用我们的文本编辑器(VS Code)打开这个 MyBlog 文件夹开始安装主题,进行博客搭建:全部按照 安知鱼主题官方文档 进行操作即可(已经非常详细了!)
还有启用主题:找到 Hexo 根目录下的 config.yml
, 找到以下配置项,把主题改为 anzhiyu
1 | # Extensions |
不要忘了安装 pug 和 stylus 渲染插件!这里是不管如何最好两个命令全部执行一下:
后面的页面配置完全参考 安知鱼主题官方文档 后面的部分即可:
文章发布
如果你看到这里,相信你的网站已经基本建设成功,恭喜了!下面我们讲解如何发布文章:在 Hexo 根目录下找到 source/_posts
,将自己的 markdown 文件放到这里,执行 hexo cl;hexo g;hexo s
就可以看到文章成功发布了,最后执行 hexo d
进行推送就大功告成了。
如果你不知道/不会 markdown 语法也有必要了解/学一下,基本会用差不多只需要 10 分钟上下,还是蛮简单的,这里推荐使用 Typora(附免费图床教程)进行编辑和学习。
2. vercel 部署
这里就有一点点复杂了,建议要有一些域名主机记录、类型和域名操作的基础,下面三两句话可能讲的不是很清楚,有问题请自行 B 站、AI。
Vercel 简介:vercel 是一个代码托管平台,它能够托管你的静态 html 界面,甚至能够托管你的 node.js 与 Python 服务端脚本,是 不想买服务器的懒人的福音!
- 首先需要一个 Vercel 账号,这里 推荐用 GitHub 账户关联,这样你就可以在 vercel 中直接托管你的 GitHub 库中的项目了,实现开发部署一步到位。
- 当你用你的 Github 账户关联并绑定手机号登录之后,点击右上角的
Add New Project
创建新的项目,之后导入选项那里选择Continue with Github
,这时候应该能看到你 Github 账号的仓库,选择你刚刚部署成功的存储静态博客的仓库<username>.github.io
右边的Import
选项,表示你要导入该仓库。 - 起一个只能有字母、数字或者或者连字符的项目名称,然后其他默认,点击
Deploy
,等待一分钟即可部署成功,部署成功后电极Continue to Dashboard
跳转到控制面板,下图所示就是控制面板,看到就代表成功部署成功了。 - 绑定自定义域名(可选):如果不想付费也有免费的域名 GitHub 源,点此开始申请免费域名。
- 点击 Vercel 控制面板右上角的
View Domains
查看当前的域,直接输入你新买的(一级)域名即可,例如demo123.com
,他会推荐你将demo123.com
重定向至www.demo123.com
,点ADD
即可,然后他会提示你添加两条解析记录,一个是@
开头的和CNAME
开头的,添加记录的方法和二级域名一致。 - 在购买域名厂商的域名后台解析记录里面添加如下记录,其中记录类型对应
Type
,主机记录对应Name
,记录值对应Value
,其他的设置默认即可。 - 回到 Vercel 刚刚查看域名的地方,如果操作没问题,应该会显示域名配置成功的提示,此时就可以通过自定义域名来访问我们搭建的网站了。
- 当你有了新的域名之后,需要
[BlogRoot]\_config.yml
文件中的url
配置项为自己的新域名,这样博客的文章链接才会正确生成。
- 点击 Vercel 控制面板右上角的
3. 博客的魔改(魔改容易出错,建议魔改前备份!!)
移除首页头图的阴影
找到 博客目录/themes/anzhiyu/source/css/_extra/home_top/top_group_banner.css
,大约在第 109 行 删除 box-shadow: 0 -109px 133px -9px #000000 inset;
或修改后面的 16 位色值大概和你图片相匹配即可
abbrlink 插件生成永久固定链接(github 源)
效果展示:地址栏会变成“自定义”的固定链接
安装
1
npm install hexo-abbrlink --save
修改 hexo
config.yml
文件中的永久链接为1
2
3
4
5permalink: posts/:abbrlink.html #文章结尾带 .html(推荐,下面这种会有一点问题,只会影响多层级分类跳转的问题,不影响网站的功能)
# 或者
permalink: posts/:abbrlink/ #文章结尾不带 .html
# 前面posts也可自定义修改做到上面一步,其实就已经可以了。下面是可选内容:将以下内容复制到 hexo
config.yml
的最底下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16# 一个 Hexo 插件,用于根据帖子正面的标题和数据生成静态帖子链接。
# https://github.com/rozbo/hexo-abbrlink
# abbrlink config
abbrlink:
alg: crc16 #support crc16(default) and crc32
rep: hex #support dec(default) and hex
drafts: false #(true)处理草稿,(false)不处理草稿。false(默认值)
# 从目录树生成类别
# 深度:要生成的目录树的最大深度应大于0
auto_category:
enable: true #true(default)
depth: #3(default)
over_write: false
auto_title: false #启用自动标题,可以按路径自动填充标题
auto_date: false #启用自动日期,它可以自动填写日期的时间今天
force: false #启用强制模式,在这种模式下,插件将忽略缓存,并为每个帖子计算abbrlink,即使它已经有了abbrlink。
添加一个统计页面
新建一个分类:根目录下执行以下代码:
1
hexo new page charts
前往博客根目录下
source/charts/index.md
,直接替换全部内容:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15---
title: 统计
type: "charts"
comments: false
aside: false
---
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/4.9.0-rc.1/echarts.min.js"></script>
<!-- 文章发布时间统计图 --> <!-- 2024-09是从2024年9月开始计算 -->
<div id="posts-chart" data-start="2024-09" style="border-radius: 8px; height: 300px; padding: 10px;"></div>
<!-- 文章标签统计图 --> <!-- data-length="10" 是显示的标签数量 -->
<div id="tags-chart" data-length="10" style="border-radius: 8px; height: 300px; padding: 10px;"></div>
<!-- 文章分类统计图 -->
<div id="categories-chart" data-parent="true" style="border-radius: 8px; height: 300px; padding: 10px;"></div>主题目录
/themes/anzhiyu/scripts/helpers
下添加一个charts.js
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
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398// charts.js
const cheerio = require('cheerio')
const moment = require('moment')
hexo.extend.filter.register('after_render:html', function (locals) {
const $ = cheerio.load(locals)
const post = $('#posts-chart')
const tag = $('#tags-chart')
const category = $('#categories-chart')
const htmlEncode = false
if (post.length > 0 || tag.length > 0 || category.length > 0) {
if (post.length > 0 && $('#postsChart').length === 0) {
if (post.attr('data-encode') === 'true') htmlEncode = true
post.after(postsChart(post.attr('data-start')))
}
if (tag.length > 0 && $('#tagsChart').length === 0) {
if (tag.attr('data-encode') === 'true') htmlEncode = true
tag.after(tagsChart(tag.attr('data-length')))
}
if (category.length > 0 && $('#categoriesChart').length === 0) {
if (category.attr('data-encode') === 'true') htmlEncode = true
category.after(categoriesChart(category.attr('data-parent')))
}
if (htmlEncode) {
return $.root().html().replace(/&#/g, '&#')
} else {
return $.root().html()
}
} else {
return locals
}
}, 15)
function postsChart (startMonth) {
const startDate = moment(startMonth || '2020-01')
const endDate = moment()
const monthMap = new Map()
const dayTime = 3600 * 24 * 1000
for (let time = startDate; time <= endDate; time += dayTime) {
const month = moment(time).format('YYYY-MM')
if (!monthMap.has(month)) {
monthMap.set(month, 0)
}
}
hexo.locals.get('posts').forEach(function (post) {
const month = post.date.format('YYYY-MM')
if (monthMap.has(month)) {
monthMap.set(month, monthMap.get(month) + 1)
}
})
const monthArr = JSON.stringify([...monthMap.keys()])
const monthValueArr = JSON.stringify([...monthMap.values()])
return `
<script id="postsChart">
var color = document.documentElement.getAttribute('data-theme') === 'light' ? '#4c4948' : 'rgba(255,255,255,0.7)'
var postsChart = echarts.init(document.getElementById('posts-chart'), 'light');
var postsOption = {
title: {
text: '文章发布统计图',
x: 'center',
textStyle: {
color: color
}
},
tooltip: {
trigger: 'axis'
},
xAxis: {
name: '日期',
type: 'category',
boundaryGap: false,
nameTextStyle: {
color: color
},
axisTick: {
show: false
},
axisLabel: {
show: true,
color: color
},
axisLine: {
show: true,
lineStyle: {
color: color
}
},
data: ${monthArr}
},
yAxis: {
name: '文章篇数',
type: 'value',
nameTextStyle: {
color: color
},
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: true,
color: color
},
axisLine: {
show: true,
lineStyle: {
color: color
}
}
},
series: [{
name: '文章篇数',
type: 'line',
smooth: true,
lineStyle: {
width: 0
},
showSymbol: false,
itemStyle: {
opacity: 1,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(128, 255, 165)'
},
{
offset: 1,
color: 'rgba(1, 191, 236)'
}])
},
areaStyle: {
opacity: 1,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(128, 255, 165)'
}, {
offset: 1,
color: 'rgba(1, 191, 236)'
}])
},
data: ${monthValueArr},
markLine: {
data: [{
name: '平均值',
type: 'average',
label: {
color: color
}
}]
}
}]
};
postsChart.setOption(postsOption);
window.addEventListener('resize', () => {
postsChart.resize();
});
postsChart.on('click', 'series', (event) => {
if (event.componentType === 'series') window.location.href = '/archives/' + event.name.replace('-', '/');
});
</script>`
}
function tagsChart (len) {
const tagArr = []
hexo.locals.get('tags').map(function (tag) {
tagArr.push({ name: tag.name, value: tag.length, path: tag.path })
})
tagArr.sort((a, b) => { return b.value - a.value })
const dataLength = Math.min(tagArr.length, len) || tagArr.length
const tagNameArr = []
for (let i = 0; i < dataLength; i++) {
tagNameArr.push(tagArr[i].name)
}
const tagNameArrJson = JSON.stringify(tagNameArr)
const tagArrJson = JSON.stringify(tagArr)
return `
<script id="tagsChart">
var color = document.documentElement.getAttribute('data-theme') === 'light' ? '#4c4948' : 'rgba(255,255,255,0.7)'
var tagsChart = echarts.init(document.getElementById('tags-chart'), 'light');
var tagsOption = {
title: {
text: 'Top ${dataLength} 标签统计图',
x: 'center',
textStyle: {
color: color
}
},
tooltip: {},
xAxis: {
name: '标签',
type: 'category',
nameTextStyle: {
color: color
},
axisTick: {
show: false
},
axisLabel: {
show: true,
color: color,
interval: 0
},
axisLine: {
show: true,
lineStyle: {
color: color
}
},
data: ${tagNameArrJson}
},
yAxis: {
name: '文章篇数',
type: 'value',
splitLine: {
show: false
},
nameTextStyle: {
color: color
},
axisTick: {
show: false
},
axisLabel: {
show: true,
color: color
},
axisLine: {
show: true,
lineStyle: {
color: color
}
}
},
series: [{
name: '文章篇数',
type: 'bar',
data: ${tagArrJson},
itemStyle: {
borderRadius: [5, 5, 0, 0],
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(128, 255, 165)'
},
{
offset: 1,
color: 'rgba(1, 191, 236)'
}])
},
emphasis: {
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(128, 255, 195)'
},
{
offset: 1,
color: 'rgba(1, 211, 255)'
}])
}
},
markLine: {
data: [{
name: '平均值',
type: 'average',
label: {
color: color
}
}]
}
}]
};
tagsChart.setOption(tagsOption);
window.addEventListener('resize', () => {
tagsChart.resize();
});
tagsChart.on('click', 'series', (event) => {
if(event.data.path) window.location.href = '/' + event.data.path;
});
</script>`
}
function categoriesChart (dataParent) {
const categoryArr = []
let categoryParentFlag = false
hexo.locals.get('categories').map(function (category) {
if (category.parent) categoryParentFlag = true
categoryArr.push({
name: category.name,
value: category.length,
path: category.path,
id: category._id,
parentId: category.parent || '0'
})
})
categoryParentFlag = categoryParentFlag && dataParent === 'true'
categoryArr.sort((a, b) => { return b.value - a.value })
function translateListToTree (data, parent) {
let tree = []
let temp
data.forEach((item, index) => {
if (data[index].parentId == parent) {
let obj = data[index];
temp = translateListToTree(data, data[index].id);
if (temp.length > 0) {
obj.children = temp
}
if (tree.indexOf())
tree.push(obj)
}
})
return tree
}
const categoryNameJson = JSON.stringify(categoryArr.map(function (category) { return category.name }))
const categoryArrJson = JSON.stringify(categoryArr)
const categoryArrParentJson = JSON.stringify(translateListToTree(categoryArr, '0'))
return `
<script id="categoriesChart">
var color = document.documentElement.getAttribute('data-theme') === 'light' ? '#4c4948' : 'rgba(255,255,255,0.7)'
var categoriesChart = echarts.init(document.getElementById('categories-chart'), 'light');
var categoryParentFlag = ${categoryParentFlag}
var categoriesOption = {
title: {
text: '文章分类统计图',
x: 'center',
textStyle: {
color: color
}
},
legend: {
top: 'bottom',
data: ${categoryNameJson},
textStyle: {
color: color
}
},
tooltip: {
trigger: 'item'
},
series: []
};
categoriesOption.series.push(
categoryParentFlag ?
{
nodeClick :false,
name: '文章篇数',
type: 'sunburst',
radius: ['15%', '90%'],
center: ['50%', '55%'],
sort: 'desc',
data: ${categoryArrParentJson},
itemStyle: {
borderColor: '#fff',
borderWidth: 2,
emphasis: {
focus: 'ancestor',
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(255, 255, 255, 0.5)'
}
}
}
:
{
name: '文章篇数',
type: 'pie',
radius: [30, 80],
roseType: 'area',
label: {
color: color,
formatter: '{b} : {c} ({d}%)'
},
data: ${categoryArrJson},
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(255, 255, 255, 0.5)'
}
}
}
)
categoriesChart.setOption(categoriesOption);
window.addEventListener('resize', () => {
categoriesChart.resize();
});
categoriesChart.on('click', 'series', (event) => {
if(event.data.path) window.location.href = '/' + event.data.path;
});
</script>`
}在
_config.anzhiyu.yml
中引用charts.js
搜Inject
插入到bottom
,注意对齐1
- <script src="https://cdn.bootcdn.net/ajax/libs/echarts/4.9.0-rc.1/echarts.min.js"></script> # 统计页面
在
_config.anzhiyu.yml
中menu
部分进行启用1
2
3分类: /categories/ || anzhiyu-icon-shapes
标签: /tags/ || anzhiyu-icon-tags
统计: /charts/ || anzhiyu-icon-charts # 注意对其进行启用
给主题侧边栏添加倒计时
效果展示: 首页个人名片下方展示倒计时
创建 JS 文件:在博客目录的
source
文件夹下创建countdown.js
文件(也可以在source
文件夹下另外新建文件夹)。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
196const CountdownTimer = (() => {
const config = {
targetDate: "2025-01-29",
targetName: "春节",
units: {
day: { text: "今日", unit: "小时" },
week: { text: "本周", unit: "天" },
month: { text: "本月", unit: "天" },
year: { text: "本年", unit: "天" }
}
};
const calculators = {
day: () => {
const hours = new Date().getHours();
return {
remaining: 24 - hours,
percentage: (hours / 24) * 100
};
},
week: () => {
const day = new Date().getDay();
const passed = day === 0 ? 6 : day - 1;
return {
remaining: 6 - passed,
percentage: ((passed + 1) / 7) * 100
};
},
month: () => {
const now = new Date();
const total = new Date(now.getFullYear(), now.getMonth() + 1, 0).getDate();
const passed = now.getDate() - 1;
return {
remaining: total - passed,
percentage: (passed / total) * 100
};
},
year: () => {
const now = new Date();
const start = new Date(now.getFullYear(), 0, 1);
const total = 365 + (now.getFullYear() % 4 === 0 ? 1 : 0);
const passed = Math.floor((now - start) / 86400000);
return {
remaining: total - passed,
percentage: (passed / total) * 100
};
}
};
function updateCountdown() {
const elements = ['eventName', 'eventDate', 'daysUntil', 'countRight']
.map(id => document.getElementById(id));
if (elements.some(el => !el)) return;
const [eventName, eventDate, daysUntil, countRight] = elements;
const now = new Date();
const target = new Date(config.targetDate);
eventName.textContent = config.targetName;
eventDate.textContent = config.targetDate;
daysUntil.textContent = Math.round((target - now.setHours(0,0,0,0)) / 86400000);
countRight.innerHTML = Object.entries(config.units)
.map(([key, {text, unit}]) => {
const {remaining, percentage} = calculators[key]();
return `
<div class="cd-count-item">
<div class="cd-item-name">${text}</div>
<div class="cd-item-progress">
<div class="cd-progress-bar" style="width: ${percentage}%; opacity: ${percentage/100}"></div>
<span class="cd-percentage ${percentage >= 46 ? 'cd-many' : ''}">${percentage.toFixed(2)}%</span>
<span class="cd-remaining ${percentage >= 60 ? 'cd-many' : ''}">
<span class="cd-tip">还剩</span>${remaining}<span class="cd-tip">${unit}</span>
</span>
</div>
</div>
`;
}).join('');
}
function injectStyles() {
const styles = `
.card-countdown .item-content {
display: flex;
}
.cd-count-left {
position: relative;
display: flex;
flex-direction: column;
margin-right: 0.8rem;
line-height: 1.5;
align-items: center;
justify-content: center;
}
.cd-count-left .cd-text {
font-size: 14px;
}
.cd-count-left .cd-name {
font-weight: bold;
font-size: 18px;
}
.cd-count-left .cd-time {
font-size: 30px;
font-weight: bold;
color: var(--anzhiyu-main);
}
.cd-count-left .cd-date {
font-size: 12px;
opacity: 0.6;
}
.cd-count-left::after {
content: "";
position: absolute;
right: -0.8rem;
width: 2px;
height: 80%;
background-color: var(--anzhiyu-main);
opacity: 0.5;
}
.cd-count-right {
flex: 1;
margin-left: .8rem;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.cd-count-item {
display: flex;
flex-direction: row;
align-items: center;
height: 24px;
}
.cd-item-name {
font-size: 14px;
margin-right: 0.8rem;
white-space: nowrap;
}
.cd-item-progress {
position: relative;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
height: 100%;
width: 100%;
border-radius: 8px;
background-color: var(--anzhiyu-background);
overflow: hidden;
}
.cd-progress-bar {
height: 100%;
border-radius: 8px;
background-color: var(--anzhiyu-main);
}
.cd-percentage,
.cd-remaining {
position: absolute;
font-size: 12px;
margin: 0 6px;
transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
}
.cd-many {
color: #fff;
}
.cd-remaining {
opacity: 0;
transform: translateX(10px);
}
.card-countdown .item-content:hover .cd-remaining {
transform: translateX(0);
opacity: 1;
}
.card-countdown .item-content:hover .cd-percentage {
transform: translateX(-10px);
opacity: 0;
}
`;
const styleSheet = document.createElement("style");
styleSheet.textContent = styles;
document.head.appendChild(styleSheet);
}
let timer;
const start = () => {
injectStyles();
updateCountdown();
timer = setInterval(updateCountdown, 600000);
};
['pjax:complete', 'DOMContentLoaded'].forEach(event => document.addEventListener(event, start));
document.addEventListener('pjax:send', () => timer && clearInterval(timer));
return { start, stop: () => timer && clearInterval(timer) };
})();添加组件配置:在
source/_data/widget.yml
中添加以下配置:1
2
3
4
5
6
7
8
9
10
11
12
13top:
- class_name: card-countdown
id_name:
name:
icon:
html: |
<div class="cd-count-left">
<span class="cd-text">距离</span>
<span class="cd-name" id="eventName"></span>
<span class="cd-time" id="daysUntil"></span>
<span class="cd-date" id="eventDate"></span>
</div>
<div id="countRight" class="cd-count-right"></div>引入 JS 文件:在
_config.anzhiyu.yml
主题配置文件的inject
配置项的bottom
中引入 JS 文件:1
2
3inject:
bottom:
- <script src="/static/countdown.js"></script>配置目标日期
1
2
3
4
5const config = {
targetDate: "2026-02-17", // 目标日期
targetName: "春节", // 名称
...
}
博客添加一个宠物挂件
顶部挂件(可选): 直接替换
themes\anzhiyu\layout\includes\bbTimeList.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
140if site.data.essay
each i in site.data.essay
if i.home_essay
- let onclick_value = theme.pjax.enable ? `pjax.loadUrl("/essay/");` : '';
- let href_value = theme.pjax.enable ? 'javascript:void(0);' : `/essay/`;
#bbTimeList.bbTimeList.container
i.anzhiyufont.anzhiyu-icon-jike.bber-logo.fontbold(onclick=onclick_value, title="即刻短文", href=href_value, aria-hidden="true")
#bbtalk.swiper-container.swiper-no-swiping.essay_bar_swiper_container(tabindex="-1")
#bber-talk.swiper-wrapper(onclick=onclick_value)
each i in site.data.essay
each item, index in i.essay_list
if index < 10
- var contentText = item.image ? item.content + ' [图片]' : (item.video ? item.content + ' [视频]' : item.content)
a.li-style.swiper-slide(href=href_value)= contentText
a.bber-gotobb.anzhiyufont.anzhiyu-icon-circle-arrow-right(onclick=onclick_value, href=href_value, title="查看全文")
img.con-animals.entered.loaded(id="new-con-animals" src="")
script(src=url_for(theme.home_top.swiper.swiper_js))
style.
#bbTimeList {
position: relative;
}
.con-animals {
display: block;
position: absolute;
max-width: 260px;
top: -85px;
z-index: 2;
}
@media screen and (max-width: 1200px) {
.con-animals {
display: none;
}
}
script.
// 将lastImageUrl移到全局作用域
window.lastImageUrl = window.lastImageUrl || '';
function setRandomImage() {
const img = document.getElementById('new-con-animals');
const imageUrls = [
"https://i1.wp.com/ruom.wuaze.com/i/2024/10/18/901216.webp",
"https://i1.wp.com/ruom.wuaze.com/i/2024/10/18/074167.webp",
"https://i1.wp.com/ruom.wuaze.com/i/2024/10/19/759434.webp",
"https://i1.wp.com/ruom.wuaze.com/i/2024/10/19/526748.webp",
"https://i1.wp.com/ruom.wuaze.com/i/2024/10/18/429029.webp"
];
let randomImage;
do {
randomImage = imageUrls[Math.floor(Math.random() * imageUrls.length)];
} while (randomImage === window.lastImageUrl);
window.lastImageUrl = randomImage;
if (img) {
img.src = randomImage;
}
}
function initializeDragImage() {
const img = document.getElementById('new-con-animals');
const container = document.getElementById('bbTimeList');
if (!img || !container) return;
if (!window.lastImageUrl) {
setRandomImage();
} else {
img.src = window.lastImageUrl;
}
let isDragging = false, wasDragged = false, startX, startLeft;
const containerWidth = container.clientWidth;
const imgWidth = img.clientWidth;
const maxLeft = containerWidth - imgWidth;
const edgeThreshold = 20;
let lastLeft = parseInt(localStorage.getItem('imgPositionLeft')) || 0;
lastLeft = Math.min(maxLeft, Math.max(0, lastLeft));
img.style.left = `${lastLeft}px`;
const savePosition = (left) => localStorage.setItem('imgPositionLeft', left);
img.addEventListener('click', () => {
if (!wasDragged) {
let currentLeft = lastLeft;
let newLeft;
if (currentLeft <= edgeThreshold) {
newLeft = Math.min(currentLeft + 200, maxLeft);
} else if (currentLeft >= maxLeft - edgeThreshold) {
newLeft = Math.max(currentLeft - 200, 0);
} else {
newLeft = currentLeft + (Math.random() < 0.5 ? -200 : 200);
newLeft = Math.max(0, Math.min(newLeft, maxLeft));
}
if (newLeft !== lastLeft) {
lastLeft = newLeft;
img.style.left = `${newLeft}px`;
savePosition(newLeft);
}
}
});
img.addEventListener('mousedown', (e) => {
isDragging = true;
wasDragged = false;
startX = e.clientX;
startLeft = lastLeft;
img.style.transition = 'none';
const onMouseMove = (e) => {
if (!isDragging) return;
wasDragged = true;
const offsetX = e.clientX - startX;
lastLeft = Math.max(0, Math.min(startLeft + offsetX, maxLeft));
requestAnimationFrame(() => {
img.style.left = `${lastLeft}px`;
});
};
const onMouseUp = () => {
isDragging = false;
img.style.transition = 'left 0.5s ease-in-out';
savePosition(lastLeft);
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
};
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
});
}
document.addEventListener('DOMContentLoaded', initializeDragImage);
document.addEventListener('pjax:success', initializeDragImage);如果你发现夜间模式会被遮挡一部分可以添加下这段 css 试试,暂且不知道会不会影响其它部分
1
2
3
4
5
6
7
8/* 小动物夜间显示优化 */
[data-theme='dark']
background: var(--anzhiyu-black)!important;
}
[data-theme='dark']
background: 0 !important;
}页脚挂件: 需要开启主题配置文件中的
footer_bar
选项,设置为true
。新建一个footer-animal.js
文件,将以下代码粘贴进去。然后在_config.anzhiyu.yml
中inject
选项的bottom
中添加<script src="/static/footer-animal.js" defer></script>
。 根据你文件位置,自行调整。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
51function initFooterAnimal() {
const footerBar = document.querySelector('#footer-bar');
if (!footerBar) return console.error('找不到指定元素');
const footerAnimal = document.createElement('div');
footerAnimal.id = 'footer-animal';
footerAnimal.innerHTML = `
<img class="animal entered loaded"
src="https://i1.wp.com/ruom.wuaze.com/i/2024/10/19/473503.webp"
alt="动物" />
`;
footerBar.insertAdjacentElement('beforebegin', footerAnimal);
const style = document.createElement('style');
style.textContent = `
#footer-animal {
position: relative;
}
#footer-animal::before {
content: '';
position: absolute;
bottom: 0;
width: 100%;
height: 36px;
background: url(https://i1.wp.com/ruom.wuaze.com/i/2024/10/19/351933.webp) repeat center / auto 100%;
box-shadow: 0 4px 7px rgba(0,0,0,.15);
}
.animal {
position: relative;
max-width: min(974px, 100vw);
margin: 0 auto;
display: block;
}
#footer-bar {
margin-top: 0 !important;
}
@media screen and (max-width: 1023px) {
#footer-animal::before {
height: 4vw;
}
}
[data-theme=dark] #footer-animal {
filter: brightness(.8);
}
`;
document.head.appendChild(style);
}
document.addEventListener('DOMContentLoaded', initFooterAnimal);
document.addEventListener('pjax:success', initFooterAnimal);
添加一个昼夜切换按钮(GitHub 源)
在路径
themes/anzhiyu/layout/includes/anzhiyu/
创建Day_night_toggle_button.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
.container
.components
.main-button
.moon
.moon
.moon
.daytime-backgrond
.daytime-backgrond
.daytime-backgrond
.cloud
.cloud-son
.cloud-son
.cloud-son
.cloud-son
.cloud-son
.cloud-son
.cloud-light
.cloud-son
.cloud-son
.cloud-son
.cloud-son
.cloud-son
.cloud-son
.stars
.star.big
.star-son
.star-son
.star-son
.star-son
.star.big
.star-son
.star-son
.star-son
.star-son
.star.medium
.star-son
.star-son
.star-son
.star-son
.star.medium
.star-son
.star-son
.star-son
.star-son
.star.small
.star-son
.star-son
.star-son
.star-son
.star.small
.star-son
.star-son
.star-son
.star-son中控台引用:
themes/anzhiyu/layout/includes/anzhiyu/console.pug
1
2
3
4
5
6
7
8
9
if theme.shortcutKey.enable
.console-btn-item#consoleKeyboard(onclick='anzhiyu.keyboardToggle()', title='快捷键开关')
a.keyboard-switch
i.naokuofont.naokuo-icon-keyboard
+ if theme.Day_night_toggle_button.console
+ #console-naoDark
+ !=partial('includes/anzhiyu/Day_night_toggle_button', {}, {cache: true})
.console-mask(onclick='anzhiyu.hideConsole()', href='javascript:void(0);')导航栏引用:
themes/anzhiyu/layout/includes/header/nav.pug
1
2
3
4
5
6#menus
!=partial('includes/header/menu_item', {}, {cache: true})
#nav-right
+ if theme.Day_night_toggle_button.nav
+ #nav-naoDark
+ !=partial('includes/anzhiyu/Day_night_toggle_button', {}, {cache: true})在路径
themes/anzhiyu/source/css/_layout/
创建Day_night_toggle_button.styl
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
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
if hexo-config('Day_night_toggle_button.console') || hexo-config('Day_night_toggle_button.nav')
.container
position relative
width 180em
height 70em
display inline-block
vertical-align bottom
transform translate3d(0, 0, 0)
.components
position fixed
width 180em
height 70em
background-color rgba(70, 133, 192, 1)
border-radius 100em
box-shadow inset 0 0 5em 3em rgba(0, 0, 0, 0.5)
overflow hidden
transition 0.7s
transition-timing-function cubic-bezier(0, 0.5, 1, 1)
cursor pointer
.main-button
margin 7.5em 0 0 7.5em
width 55em
height 55em
background-color rgba(255, 195, 35, 1)
border-radius 50%
box-shadow 3em 3em 5em rgba(0, 0, 0, 0.5), inset -3em -5em 3em -3em rgba(0, 0, 0, 0.5), inset 4em 5em 2em -2em rgba(255, 230, 80, 1)
transition 1.0s
transition-timing-function cubic-bezier(0.56, 1.35, 0.52, 1.00)
.moon
position absolute
background-color rgba(150, 160, 180, 1)
box-shadow inset 0em 0em 1em 1em rgba(0, 0, 0, 0.3)
border-radius 50%
transition 0.5s
opacity 0
&:nth-child(1)
top 7.5em
left 25em
width 12.5em
height 12.5em
&:nth-child(2)
top 20em
left 7.5em
width 20em
height 20em
&:nth-child(3)
top 32.5em
left 32.5em
width 12.5em
height 12.5em
.daytime-backgrond
position absolute
border-radius 50%
transition 1.0s
transition-timing-function cubic-bezier(0.56, 1.35, 0.52, 1.00)
&:nth-child(2)
top -20em
left -20em
width 110em
height 110em
background-color rgba(255, 255, 255, 0.2)
z-index -2
&:nth-child(3)
top -32.5em
left -17.5em
width 135em
height 135em
background-color rgba(255, 255, 255, 0.1)
z-index -3
&:nth-child(4)
top -45em
left -15em
width 160em
height 160em
background-color rgba(255, 255, 255, 0.05)
z-index -4
.cloud,
.cloud-light
transform translateY(10em)
transition 1.0s
transition-timing-function cubic-bezier(0.56, 1.35, 0.52, 1.00)
.cloud-son
position absolute
background-color #fff
border-radius 50%
z-index -1
transition transform 6s, right 1s, bottom 1s
&:nth-child(6n
& + 1)
right -20em
bottom 10em
width 50em
height 50em
& + 2)
right -10em
bottom -25em
width 60em
height 60em
& + 3)
right 20em
bottom -40em
width 60em
height 60em
& + 4)
right 50em
bottom -35em
width 60em
height 60em
& + 5)
right 75em
bottom -60em
width 75em
height 75em
& + 6)
right 110em
bottom -50em
width 60em
height 60em
.cloud
z-index -2
.cloud-light
position absolute
right 0em
bottom 25em
opacity 0.5
z-index -3
.stars
transform translateY(-125em)
z-index -2
transition 1.0s
transition-timing-function cubic-bezier(0.56, 1.35, 0.52, 1.00)
.big
--size 7.5em
.medium
--size 5em
.small
--size 3em
.star
position absolute
width calc(2*var(--size))
height calc(2*var(--size))
&:nth-child(1)
top 11em
left 39em
&:nth-child(2)
top 39em
left 91em
&:nth-child(3)
top 26em
left 19em
&:nth-child(4)
top 37em
left 66em
&:nth-child(5)
top 21em
left 75em
&:nth-child(6)
top 51em
left 38em
.star-son
float left
&:nth-child(1)
--pos left 0
&:nth-child(2)
--pos right 0
&:nth-child(3)
--pos 0 bottom
&:nth-child(4)
--pos right bottom
.star-son
width var(--size)
height var(--size)
background-image radial-gradient(circle var(--size) at var(--pos), transparent calc(95% - 1px), #fff 95%)
.components
.main-button
&:hover
transform: translateX(10em);
& ~ .daytime-backgrond
&:nth-child(2)
transform: translateX(10em);
&:nth-child(3)
transform: translateX(7em);
&:nth-child(4)
transform: translateX(4em);
& ~ .cloud .cloud-son
&:nth-child(1)
right -24em
bottom 10em
&:nth-child(2)
right -12em
bottom -27em
&:nth-child(3)
right 17em
bottom -43em
&:nth-child(4)
right 46em
bottom -39em
&:nth-child(5)
right 70em
bottom -65em
&:nth-child(6)
right 109em
bottom -54em
& ~ .cloud-light .cloud-son
&:nth-child(1)
right -23em
bottom 10em
&:nth-child(2)
right -11em
bottom -26em
&:nth-child(3)
right 18em
bottom -42em
&:nth-child(4)
right 47em
bottom -38em
&:nth-child(5)
right 74em
bottom -64em
&:nth-child(6)
right 110em
bottom -55em
@keyframes naoStar {
0%,
20% {
transform: scale(0);
}
20%,
100% {
transform: scale(1);
}
}
// 云朵动画
@keyframes naoCloud {
0% {
transform: translate(2em, -2em);
}
50% {
transform: translate(-2em, 2em);
}
100% {
transform: translate(2em, -2em);
}
}
[data-theme="light"] #console-naoDark,
[data-theme="light"] #nav-naoDark
.container
.cloud-son
transform scale(1)
transition-timing-function cubic-bezier(0.56, 1.35, 0.52, 1.00)
transition 1s
animation-iteration-count infinite
animation-direction alternate
animation-timing-function ease-in-out
&:nth-child(6n + 1)
animation-name naoCloud
animation-duration 4.5s
&:nth-child(6n + 2)
animation-name naoCloud
animation-duration 5.1s
&:nth-child(6n + 3)
animation-name naoCloud
animation-duration 5.9s
&:nth-child(6n + 4)
animation-name naoCloud
animation-duration 6.3s
&:nth-child(6n + 5)
animation-name naoCloud
animation-duration 4.7s
&:nth-child(6n + 6)
animation-name naoCloud
animation-duration 5s
[data-theme="dark"] #console-naoDark,
[data-theme="dark"] #nav-naoDark
.container
.components
background-color: rgba(25,30,50,1)
.main-button
transform: translateX(110em)
background-color: rgba(195, 200,210,1)
box-shadow: 3em 3em 5em rgba(0, 0, 0, 0.5), inset -3em -5em 3em -3em rgba(0, 0, 0, 0.5), inset 4em 5em 2em -2em rgba(255, 255, 210,1)
.moon
&:nth-child(1)
opacity: 1
&:nth-child(2)
opacity: 1
&:nth-child(3)
opacity: 1
.daytime-backgrond
&:nth-child(2)
transform: translateX(110em)
&:nth-child(3)
transform: translateX(80em)
&:nth-child(4)
transform: translateX(50em)
.cloud,
.cloud-light
transform translateY(80em)
.stars
transform translateY(-62.5em)
opacity: 1
.star
transform scale(1)
transition-timing-function cubic-bezier(0.56, 1.35, 0.52, 1.00)
transition 1s
animation-iteration-count infinite
animation-direction alternate
animation-timing-function linear
&:nth-child(1)
animation-name naoStar
animation-duration 3.5s
&:nth-child(2)
animation-name naoStar
animation-duration 4.1s
&:nth-child(3)
animation-name naoStar
animation-duration 4.9s
&:nth-child(4)
animation-name naoStar
animation-duration 5.3s
&:nth-child(5)
animation-name naoStar
animation-duration 3s
&:nth-child(6)
animation-name naoStar
animation-duration 2.2s
.components
.main-button
&:hover
transform: translateX(100em)
& ~ .daytime-backgrond
&:nth-child(2)
transform: translateX(100em)
&:nth-child(3)
transform: translateX(73em)
&:nth-child(4)
transform: translateX(46em)
& ~ .stars .star
&:nth-child(1)
top: 10em
left: 36em
&:nth-child(2)
top: 40em
left: 87em
&:nth-child(3)
top: 26em
left: 16em
&:nth-child(4)
top: 38em
left: 63em
&:nth-child(5)
top: 20.5em
left: 72em
&:nth-child(6)
top: 51.5em
left: 35em
#nav-right
if hexo-config('Day_night_toggle_button.console')
#console-naoDark
.container
font-size: 0.85px
if hexo-config('Day_night_toggle_button.nav')
#nav-naoDark
.container
font-size: 0.5px添加按钮交互:在路径
themes/anzhiyu/source/js/main.js
添加如下:1
2
3
4
5
6
7
8
9
10window.refreshFn = function () {
initAdjust();
themeColorMeta = document.querySelector('meta[name="theme-color"]');
pageHeaderEl = document.getElementById("page-header");
navMusicEl = document.getElementById("nav-music");
consoleEl = document.getElementById("console");
addDarkModeEventListener("console", ".darkmode_switchbutton");
+ addDarkModeEventListener("nav-naoDark", ".components");
+ addDarkModeEventListener("console-naoDark", ".components");主题配置文件
_config.anzhiyu.yml
添加:1
2
3
4# 昼夜切换按钮
Day_night_toggle_button:
console: true # 中控台
nav: true # 导航栏
为主页文章卡片添加擦亮动画效果
新增 css 内容:新建文件
source/css/home.css
或在已引入的 css 中新增以下内容1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#recent-posts > .recent-post-item:not(a)::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 200%;
background: linear-gradient(to right, transparent, white, transparent);
transform: translateX(-200%);
transition: transform 0.5s linear;
z-index: 1;
}
#recent-posts > .recent-post-item:not(a):hover::before {
transform: translateX(100%) skewX(-60deg);
}引入内容:在
_config.anzhiyu.yml
主题配置文件下inject
配置项中head
处引入home.css
文件1
2
3inject:
head:
- <link rel="stylesheet" href="/css/home.css"> # 首页文章卡片擦亮效果
文章加密插件(GitHub 源)
在根目录执行以下命令:
1
npm install --save hexo-blog-encrypt
Front matter 配置方法:
1
2
3
4
5
6
7
8
9
10
11
12
title: Hello World
tags:
- 作为日记加密
date: 2016-03-30 21:12:21
password: mikemessi
abstract: 有东西被加密了, 请输入密码查看。
message: 您好, 这里需要密码。
theme: xray
wrong_pass_message: 抱歉, 这个密码看着不太对, 请再试试。
wrong_hash_message: 抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容。如果你在 front-matter 里添加了
password
字段,这篇文章就会 单独加密,优先级高于标签加密。字段名 说明 示例 password
设置该文章的专属访问密码 mikemessi
,用户输入正确才能解密查看内容abstract
单独覆盖全局摘要提示(可选) 比如为某一篇文章自定义一段介绍 message
单独覆盖全局提示信息 可针对文章内容使用不同文案 wrong_pass_message
密码错误时的反馈文案(可选) 便于 UX 个性化 wrong_hash_message
解密内容校验失败的提示(可选) 一般不必修改 注意:
- 如果同时设置了全局标签加密和文章局部密码加密,文章 front-matter 中的
password
优先。 abstract
和message
都是展示在前端的提示文字,不影响实际加密逻辑。
- 如果同时设置了全局标签加密和文章局部密码加密,文章 front-matter 中的
配置文件
[BlogRoot]\_config.yml
中针对 tags 的加密1
2
3
4
5
6
7
8
9
10# Security
encrypt: # hexo-blog-encrypt
abstract: 有东西被加密了, 请输入密码查看。
message: 您好, 这里需要密码。
tags:
- {name: tagName, password: 密码A}
- {name: tagName, password: 密码B}
theme: xray
wrong_pass_message: 抱歉, 这个密码看着不太对, 请再试试。
wrong_hash_message: 抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容。
字段名 | 说明 | 示例/备注 |
---|---|---|
abstract |
文章加密后显示的摘要/预览文字 | 提示用户文章是加密的 |
message |
加密文章的提示语 | 通常告诉用户需要输入密码 |
tags |
指定标签加密:只要文章含有指定 name 的标签就会被加密,密码为对应的 password |
适用于批量加密 |
wrong_pass_message |
密码错误时显示的消息 | 可自定义提示 |
wrong_hash_message |
解密成功但内容校验失败时显示的消息(一般发生在内容被篡改后) | 多用于调试场景 |