置顶文章

  最近想要做一篇博客置顶给所有的人看
  本来还以为只要不添加时间就可以自动置顶了,结果发现不可行

  随后网上搜了一下解决方案,其实Hexo还有人开发了插件来解决这个问题,真的贴心。 文章

1
npm install hexo-generator-index-pin-top --save

  安装这个插件,并且在文章的信息里面添加 top: true
  真是方便得很。

代码注释颜色区分

  自从用上了 vscode 的 Better Comments 插件之后
  我写代码都喜欢加上 NOTE 标记来区分代码注释和说明注释
  Better Comments 添加了颜色加以区分,也让我写代码贼喜欢加说明

  但是目前博客上使用的代码块还缺少这一功能,要如何才能实现呢?

1
2
3
4
# test
# NOTE test
# TODO test
# ! test
1
2
3
4
// test
// NOTE test
// TODO test
// ! test

  在 main.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

// Note 添加 comment 特殊样式
$(".comment").each(function(){
let py_long_comment = $(this).text().slice(0,6).toLowerCase()
let c_long_comment = $(this).text().slice(0,7).toLowerCase()
let py_short_comment = $(this).text().slice(0,3).toLowerCase()
let c_short_comment = $(this).text().slice(0,4).toLowerCase()

if (py_long_comment == "# note" || c_long_comment == "// note"){
$(this).css({
"color":"#FFD700",
"font-style": "normal"
})
}
else if (py_long_comment == "# todo" || c_long_comment == "// todo"){
$(this).css({
"color":"#FF8C00",
"font-style": "normal"
})
}
if (py_short_comment == "# !" || c_short_comment == "// !"){
$(this).css({
"color":"#FF2D00",
"font-style": "normal"
})
}
})

评论自动初始化

  参考了这一篇博客文章

  由于公司访问外网需要通过代理实现。
  还需要在请求上加上 proxy 代理参数 文章参考

  经过我自己的测试,我发现我的博客评论是通过抓取 github Issue 的标签实现的。
  而 gittalk 的设置上设置了标签是通过对 window.location.pathname 变量 MD5 来实现的
  还好之前抄代码留的注释还是解释得挺好的, md5 就是为了让标记小于50个字节

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<section id="comments">
<link href="https://cdnjs.cloudflare.com/ajax/libs/gitalk/1.2.2/gitalk.min.css" rel="stylesheet">
<div class="gitalk" style="width:90%;margin:auto;">
<div id="gitalk-container"></div>
<script type="text/javascript">
require(["https://cdnjs.cloudflare.com/ajax/libs/gitalk/1.2.2/gitalk.min.js","https://cdnjs.cloudflare.com/ajax/libs/blueimp-md5/2.10.0/js/md5.min.js"], function (Gitalk,md5) {

const gitalk = new Gitalk({
clientID: '<%= client_id%>',
clientSecret: '<%= client_secret%>',
repo: '<%= repo%>',
owner: '<%= githubID%>',
admin: ['<%= githubID%>'],
id: md5(location.pathname), // Ensure uniqueness and length less than 50
distractionFreeMode: false // Facebook-like distraction free mode
})

gitalk.render('gitalk-container')

});
</script>
</div>
</section>

  因此同理自动生成的标签也需要添加这个 id 号才能抓取到数据。
  下面就是我经过修改的 自动生成 评论的脚本

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
// 参考 https://blog.csdn.net/daihaoxin/article/details/84958369
const request = require("request");
const fs = require("fs");
const path = require("path");
const url = require("url");
const xmlParser = require("xml-parser");
const YAML = require("yamljs");
const cheerio = require("cheerio");
const md5 = require("md5")

// 根据自己的情况进行配置
const config = {
username: "FXTD-ODYSSEY", // GitHub 用户名
token: "GitHub Token", // GitHub Token
repo: "FXTD-odyssey.github.io", // 存放 issues的git仓库
// sitemap.xml的路径,commit.js放置在根目录下,无需修改,其他情况自行处理
sitemapUrl: path.resolve(__dirname, "./public/sitemap.xml"),
kind: "Gitalk", // "Gitalk" or "Gitment"
client_id: "client_id",
client_secret: "client_secret"
};
let issuesUrl = `https://api.github.com/repos/${config.username}/${config.repo}/issues?access_token=${config.token}&client_id=${config.client_id}&client_secret=${config.client_secret}`;

let requestGetOpt = {
proxy: "http://127.0.0.1:12639", // 公司网络需要代理进行访问
url: `${issuesUrl}&page=1&per_page=100`,
json: true,
headers: {
"User-Agent": "github-user"
}
};
let requestPostOpt = {
...requestGetOpt,
url: issuesUrl,
method: "POST",
form: ""
};

console.log("开始初始化评论...");

(async function () {
console.log("开始检索链接,请稍等...");

try {
let websiteConfig = YAML.parse(fs.readFileSync(path.resolve(__dirname, "./_config.yml"), "utf8"));

let urls = sitemapXmlReader(config.sitemapUrl);
console.log(`共检索到${urls.length}个链接`);

console.log("开始获取已经初始化的issues:");

let num = 1;
let issues = [];
let data = await send(requestGetOpt);
issues = issues.concat(data);
while (data.length == 100) {
num++;
data = await send({ ...requestGetOpt, url: `${issuesUrl}&page=${num}&per_page=100` });
issues = issues.concat(data);
}
console.log(`已经存在${issues.length}个issues`);

// NOTE 过滤出 gittalk 的 issue
issues = issues.filter(issue => {
// NOTE 检测是否带有 gittalk 标签
let gittalk = issue.labels.filter(label => {
return label.name == "Gitalk"
})

// NOTE 检测是否带有以前带三个日期的评论
let match = issue.body.search(/\d+\/\d+\/\d+/i);

let match2 = issue.body.search("/posts/");
return gittalk.length > 0 && match == -1 && match2 != -1;
})

// NOTE 过滤掉非文章的链接
urls = urls.filter(url => {
return url.search("/posts/") != -1;
})


let notInitIssueLinks = urls.filter((link) => {
link = link.split("/");
html = link[link.length - 1]
return !issues.find((issue) => {
return issue.body.includes(html);
});
});

if (notInitIssueLinks.length > 0) {
console.log(`本次有${notInitIssueLinks.length}个链接需要初始化issue:`);
console.log(notInitIssueLinks);

let initRet = await notInitIssueLinks.map(async (item) => {
// console.log(item)
item = item.replace("blog.l0v0.com", "fxtd-odyssey.github.io");
let html = await send({ ...requestGetOpt, url: item });
let $ = cheerio.load(html);
let title = $("title").text();
let description = $(".article-entry h1").text();
let pathLabel = url.parse(item).path;
let body = `${item}<br><br>${description}`;
let form = JSON.stringify({ body, labels: [config.kind, md5(pathLabel)], title });
return send({ ...requestPostOpt, form });
});
console.log(`已完成${initRet.length}个!`);
console.log("可以愉快的发表评论了!");
} else {
console.log("本次发布无新增页面,无需初始化issue!!");
}
} catch (e) {
console.log(`初始化issue出错,错误如下:`);
console.log(e);
} finally {

}
})();

function sitemapXmlReader(file) {
let data = fs.readFileSync(file, "utf8");
let sitemap = xmlParser(data);
return sitemap.root.children.map(function (url) {
let loc = url.children.filter(function (item) {
return item.name === "loc";
})[0];
return loc.content;
});
}


function send(options) {
return new Promise(function (resolve, reject) {
request(options, function (error, response, body) {
if (!error) {
resolve(body);
} else {
reject(error);
}
});
});
}

  原理也很简单,借助 Github 提供的 Restful API , 通过用户设置的权限token进行验证就可以通过代码自动处理了。

总结

  进一步完善了博客的一些配套设置。
  如果大家有什么东西想要添加的,可以在下面评论区一起探讨。