Hexo 添加 Utterance 评论功能

每逢看到大佬们的精彩文章,感慨甚多之际,不能留言把欢甚是遗憾。
缺少了留言支持、请教解惑、互相探讨,总感觉博客没有灵魂。


最新版本Next主题已集成Utterance,So,此方法已弃用 ❕❕❕


废话连篇

曾记得,2016 年端午节,在Github Pages上写下了人生中的第一篇博客,那时就用的Hexo + Next主题,时至今日,一直对Hexo + Next甚是喜爱,感谢大佬,感谢开源 🙏 。

期间,经历了换工作、换电脑、换域名、换托管,诸多原因导致博客遗失,不过也是甚好,不能守着过去,要拥抱现在和未来(不应该是拥抱开源吗?)。

之前使用过网易云跟帖,大家都戏称灌水专用,现在业已关闭。

接着使用了来必力,一个来自韩国的评论插件,国内访问甚是感人,至于大佬们的反向代理,那时心有余而力不足,遂卒。

后来使用了valine,依托于LeanCloud在国内运营,对用户甚是友好,界面也是简洁清新,让人看一眼就喜爱,而且支持阅读统计等诸多功能,之后便一直使用。

偶然间,在知乎上闲逛时,发现了一位大兄关于评论插件的分析和感想,现在依稀记得的一句话就是“无论第三方插件的使用有多友好,数据都存在第三方,哪天他们歇业停工了,数据一样丢失。”,之后就对此耿耿于怀(当然不是对说这句话的仁兄耿耿于怀)。

重建博客之际,对评论插件抱着谨慎的态度选之又选,决定将数据存在Github上,至于歇业停工,既然博客数据都不存在了,还留着评论数据作甚,就让他们同生共死吧。

GitalkGitment最先映入眼帘,之后在Github上发现Gitment好久没有更新了,只剩下一个选择。

Hexo官方集成了Gitalk,轻车熟路的做好设置,hexo clean | g | s三部曲之后,熟悉的框框出现,然鹅,发现每篇文章都要手动初始化,翻阅官方 Wiki发现了自动初始化的脚本,底部有原作者 的链接,遂前往,准备学习膜拜一番,看了大佬的思路解析,大呼过瘾之际也感落寞,原因无他,就是自己不会Ruby。在准备留言评论之际,发现又有大佬给出了使用Python初始化的思路,用轮子不是目的,读懂造轮子的思路学习造轮子,岂不快哉。

进入文章,阅读之际,大佬既感且叹地推荐了一个新的评论插件utterances,揣着疑惑的心去官网,去官方仓库查看了一番,发现没有 Wiki,也没有文档,善用搜索引擎的我,搜索一番之后发现,似乎Next主题之前的某个版本集成过,但翻阅了现在的版本又毫无所获,教程都是根据集成时的方法写的,对我无用。

在这里,不得不提的是Hexo的一项前瞻性功能代替配置文件代替主题配置文件,再也不用像之前一样,想要实现某个功能就去修改官方文件,它不破坏官方文件的完整性,可以无痛更新,之前最头疼的一件事儿就是拉取官方更新之后合并冲突

这次重建博客,所有非官方功能,如 404、音乐、footer,都使用注入实现,我对这项功能的称呼,暂且这么叫吧。

以上都是废话,下面进入正题:

首先,需要一个用来存储评论的仓库

  • 你可以新建一个仓库;
  • 当然,也可以像我一样,存放在博客仓库的 Issues 中,毕竟我已经承诺了它们同生共死,说到就要做到;
  • Issues 无法删除,请谨慎选择,防止过多的无用 Issues 带来烦恼(设置 utterances 的时候,这句话依然有效!);

安装 utterances

  • 点击这里打开安装页面,然后点击右上角的安装

  • 按下安装按钮,(不不不,不够严谨,按下是 201,抬起才是 202),你会跳转到:

    第二步

    如图所示的页面,选择第一步中创建的仓库或已有的仓库,然后点击安装,请记住仓库名,因为接下来要用;

  • 接下来,会跳转到设置页面;

设置 utterances

  • 在这里,请务必填写你在上一步中选择的仓库,并在前面加上仓库的所有者:

    第三步

  • 当然,如果你比较调皮,没有填写上一步中选择的仓库,还是有补救办法的,点击这里,其实就是安装页面,你会跳转到安装页面,你发现右上角的安装不见了,取而代之的是配置,就是它了,去配置页面修改吧;

  • 至于这里,是配置 utterances 创建新的 Issues 时,给 Issues 起的名儿:

    配置

    请自由发挥,因为使用了abbrlink,链接并不显示文章名称,所以我就选图中所示的选项了,自由发挥的同学,玩的开心;

  • 这里是选填选项,给 utterances 创建的 Issues 设置标签:

    设置标签

  • Theme就不用说了吧,主题选自己喜欢的,没喜欢的?给官方提交一个新主题;

  • 接下来就是重头戏了,上面所有的选项都是为它服务的:

    script

    复制 script 并添加到你想要评论出现的地方,bingo!

个人配置

因为要用注入来实现评论功能,那就不能修改官方的模板,自己撸了个 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
/* utterances 评论插件 */

// 初始化
window.addEventListener("DOMContentLoaded", function () {
query2add();
});

// pjax 使用 pushState() 不会触发 hashchange 事件,需要拦截
var _wr = function (type) {
var orig = history[type];
return function () {
var e = new Event(type);
e.arguments = arguments;
window.dispatchEvent(e);
// 注意事件监听在url变更方法调用之前 也就是在事件监听的回调函数中获取的页面链接为跳转前的链接
var rv = orig.apply(this, arguments);
return rv;
};
};

history.pushState = _wr("pushState");

// 监听 change 事件
window.addEventListener("pushState", function (e) {
// e && e.arguments.length > 2 && e.arguments[2]
query2add();
});

// 加载 utterance 插件
function loadUtterance() {
let js = document.createElement("script");
/* 以下内容改成第三步生成的配置 */
js.setAttribute("src", "https://utteranc.es/client.js");
js.setAttribute("repo", "Undeio/undeio.github.io");
js.setAttribute("issue-term", "title");
js.setAttribute("theme", "github-light");
js.setAttribute("crossorigin", "anonymous");
js.setAttribute("async", "async");
/* 以上内容需要修改 */
// 添加到主体部分的末尾
document.getElementsByClassName("main-inner")[0].appendChild(js);
}

// 是否已存在组件
function query2add() {
// 只有正文页面才有 post-copyright,也就是最后的版权声明
// 当然,你也可以找一个自己正文才有的标识进行判断
let postCopyRight = document.getElementsByClassName("post-copyright");
if (postCopyRight && postCopyRight[0]) {
// 存在评论就放弃添加
let utterances = document.getElementsByClassName("utterances");
if (utterances && utterances[0]) {
return;
}
loadUtterance();
}
}

无图无真相

真相

最终效果

效果

才疏学浅,实现比较粗糙,如果你有更好的实现,请给我留言。