【笔记】通过Hexo过滤器实现贡献日历

前言

通过Hexo过滤器实现贡献日历

创建贡献页面

1
hexo new page contribute

编写脚本

  • hexo/scripts目录下创建.js文件作为Hexo脚本

site_data:这个常量要改成自己的建站时间

hexo/scripts/GenerateContributeEchartsScript.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
const log = require('hexo-log')();
const fs = require('hexo-fs');

/**
* 生成贡献日历
*/

// 日期计数器
const data_map = new Map();

hexo.extend.filter.register('before_post_render', function (data) {

// 跳过所有非文章的页面
if (!/^_posts\/.*?\.md/.test(data.source)) {
// console.log(data.source, "跳过生成贡献日历")
return data;
}
// console.log(data.source, "执行生成贡献日历")

// 当前文章的创建日期
const post_time_obj = new Date(data.date);
const post_time_string = `${post_time_obj.getFullYear()}-${post_time_obj.getMonth() + 1}-${post_time_obj.getDate()}`;

// 计数器计数
if (data_map.get(post_time_string)) {
// 如果存在当前日期的键就将计数器自增1
data_map.set(post_time_string, data_map.get(post_time_string) + 1);
} else {
// 如果不存在当前日期的键就将计数器置1
data_map.set(post_time_string, 1);
}

return data;
});

hexo.extend.filter.register('before_exit', async function () {

// 分年度存储计数器
const data_map_year = new Map();

// 从建站那一年元旦遍历到明年元旦的时间,不存在的日期就将计数器置0
const site_data = new Date("2019-11-01");
const start_data = new Date(`${site_data.getFullYear()}-01-01`);
const end_data = new Date(`${new Date().getFullYear() + 1}-01-01`);
for (let i = start_data; i < end_data; i.setDate(i.getDate() + 1)) {
// 当前遍历的年月日
const i_date = `${i.getFullYear()}-${i.getMonth() + 1}-${i.getDate()}`;
// 在分年度存储计数器中是否存在当前年的键,不存在就创建
if (!data_map_year.get(i.getFullYear())) {
data_map_year.set(i.getFullYear(), []);
}
// 计数器中如果不存在当前日期的键值对,就将当前日期的计数器,直接存储到分年度存储计数器中,设置为0
let data_map_year_one = "";
if (!data_map.get(`${i.getFullYear()}-${i.getMonth() + 1}-${i.getDate()}`)) {
data_map_year_one = [i_date, 0];
}
// 计数器中如果存在当前日期的键值对,就将键值对存储到分年度存储计数器中
else {
data_map_year_one = [i_date, data_map.get(`${i.getFullYear()}-${i.getMonth() + 1}-${i.getDate()}`)];
}
data_map_year.get(i.getFullYear()).push(data_map_year_one);
}

// 准备将要写入文件的内容
let file_content = "";
file_content += `---\ntitle: 貢獻\ncomments: false\n---\n`;
// 从今年遍历到建站那一年
for (let i = new Date().getFullYear(); i >= site_data.getFullYear(); i--) {
file_content += `\n## ${i}年度\n\n{% echarts 700 100 %}\n{\n // 悬浮窗\n tooltip: {\n padding: 10,\n borderColor: "#FFF",\n borderWidth: 1,\n formatter: function (a) {\n var b = a.value;\n return \`<div style="font-size: 14px;">\${b[0]}: \${b[1]}</div>\`;\n }\n },\n visualMap: {\n show: false,\n min: 1,\n max: 5,\n minOpen: true,\n maxOpen: true,\n calculable: false,\n inRange: {\n symbol: "rect",\n color: ["#ebedf0", "#c6e48b", "#7bc96f", "#239a3b", "#196127"]\n },\n itemWidth: 12,\n itemHeight: 12,\n type: "piecewise",\n orient: "horizontal",\n left: "center",\n top: 0\n },\n // 主体\n calendar: {\n top: 0,\n range: "${i}",\n left: "center",\n cellSize: [13, 13],\n splitLine: {\n // 月份分割线\n show: false\n },\n name: {\n textStyle: {\n color: "#3C4858"\n }\n },\n itemStyle: {\n borderColor: "#fff",\n borderWidth: 2\n },\n yearLabel: {\n // 左侧年份\n show: false\n },\n monthLabel: {\n // 上面月份\n show: false\n },\n dayLabel: {\n // 左侧星期\n show: false\n }\n },\n series: {\n type: "heatmap",\n coordinateSystem: "calendar",\n calendarIndex: 0,\n data: ${JSON.stringify(data_map_year.get(i))}\n }\n}\n{% endecharts %}\n`;
}
// 写入文件
fs.writeFile("./source/contribute/index.md", file_content);
log.i("贡献日历更新完成");
});

完成