0x10 - 为 Hexo 添加开源评论系统 "ISSO"

TL;DR 太长不看总结

  • 环境:Ubuntu 22.04 LTS + Docker
  • 主体:Hexo NexT v8.19.1
  • Hexo-NexT 对于评论的官方说明 Hexo
  • ISSO 官方指南 ISSO

需求与目的

博客如果没有评论功能,总觉的会是少了些什么。
好的留言本身经历过时间的沉淀,最终留言本身也会变成博客的一部分。沉淀在网页之中,多年以后重温总有种回忆往昔的感受。

于是乎,为了提升网页的交互能力,在此,提出新的需求。

我们需要评论区

选用平台

Hexo NexT 官方就支持多种多样的评论系统,国外的 Disqus,DisqusJS,Gitalk,国内的畅言之类的。

考虑到迁移和部署的成本,以及管理的便捷性,最终还是选用了开源框架 ISSO 来作为我们的评论平台。

ISSO 服务

ISSO (Ich schrei sonst) 是一个搭建在 Python 和 JS 上的轻量评论服务。基本可以替换 Disqus 使用。
官方的 介绍页面 给出了几种不同的安装部署方式。

ISSO 服务部署

我们这里使用 docker 的方式来简单部署。
首先获取 docker 镜像,创建对应的配置文件夹。

1
2
3
$ docker pull ghcr.io/isso-comments/isso:latest # 国内访问 ghcr.io 的速度有点捉急
$ mkdir -p /var/lib/isso # 可以选自己指定的文件夹
$ vi /var/lib/isso/isso.cfg # 编辑对应的配置文件

ISSO 的配置选项比较多,官方有一个,可以参考 官方的介绍
这个配置的选项主要目的是为了指定对应的数据库路径,基本的访问限制,服务端口之类的。
更高级的功能,例如邮件通知、访问限制、管理员功能之类的,都需要额外配置。

如果只是需要基本的配置使用的话,下面是一个简单的例子。

isso.cfg
1
2
3
4
5
6
[general]
dbpath = /var/lib/isso/comments.db
host = https://example.com
gravatar = true
[server]
listen = http://localhost:8080

ISSO 使用 CORS (跨源资源共享) 对网站源数据进行保护,这里的 host 限制了具体能够访问的源地址。可以理解为一个域名白名单,可以设置多行。

Gravatar 是一个免费的全球通用头像平台,通过具体的邮箱地址可以获取到特定的头像,对于缺少登录方式的博客来说用于标记每个人的评论是再合适不过了。
可以在上面使用 gravatar 的选项来控制开闭。

配置好后执行以下脚本

1
2
3
docker run -d --name isso -p 127.0.0.1:8080:8080 \
-v /var/lib/isso:/var/lib/isso \
ghcr.io/isso-comments/isso:latest

这样最简单的评论服务就部署好了。

1
$ docker logs isso # 这样查看运行的日志

Nginx 反向代理

我们不希望外部链接能够通过我们的端口号直接访问到我们的服务,所以我们可以设置一下反向代理

nginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
http {
server {
# 80 转 443,禁用 http,全部使用 https
server_name example.com
listen 80;
return 301 https://$server_name$request_uri;
#rewrite ^(.*) https://$server_name$1 permanent;
}
server {
listen 443 ssl;
# listen 80;
server_name example.com;
...
location ^~ /isso/ {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
...
}
}

这样所有访问 https://example.com/isso 的请求都会走 nginx 反向代理到本地的 8080 端口,保证只有这个接口能访问到我们内部的服务。

在 Hexo-NexT 里启用

由于 Hexo NexT 主题的版本迭代比较快,可能会出现配置不存在的情况,最好是能更新到相对比较新的版本来获取完整的支持。

配置文件

主要是在 yml 填写 activate 的方式,并在 isso 内补充对应的地址。

_config.next.yml
1
2
3
4
5
6
7
comments:
style: tabs
active: isso
storage: true
lazyload: false
nav:
isso: https://example.com/isso/

如果没有找到对应的选项,记得确认一下你的 NexT 版本是否需要更新。

配置 ISSO 参数的方式

ISSO 除了一些可以在 config 内配置的字段以外,还存在一些可以设置的字段。
例如指定评论区显示的字,指定语言,指定默认值之类的。

文件可以在 themes/next/source/js/third-party/comments/isso.js 这里找到
举例来说,我想更改部分文本框没有文字时显示的内容,就可以这么改:

themes/next/source/js/third-party/comments/isso.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* global NexT, CONFIG */

document.addEventListener('page:loaded', () => {
if (!CONFIG.page.comments) return;

NexT.utils.loadComments('#isso-thread')
.then(() => NexT.utils.getScript(`${CONFIG.isso}js/embed.min.js`, {
attributes: {
dataset: {
isso: `${CONFIG.isso}`,
issoCss: true,
},
'data-isso-lang': 'zh',
'data-isso-postbox-text-text-zh': "在这里发表你的想法吧~ (至少 3 个字符)",
'data-isso-postbox-author-placeholder-text-zh': "匿名",
'data-isso-postbox-email-placeholder-text-zh': "abc@abc.com",
'data-isso-postbox-website-placeholder-text-zh': "https://abc.com",
},
parentNode: document.querySelector('#isso-thread')
}));
});

还有很多字段和配置可以修改,可以参考 官方的文档

修改 ISSO 样式 CSS

解决了上述的问题,当我们部署的时候,我们发现它显示的部分和我们的主体并不是那么契合,那么该怎么办呢?

作者自己没有找到特别简单的方式 _(:з」∠)_,不管怎么做都绕不开手动修改 CSS 文件。
简单讲一下作者的修改思路。

修改源文件法

ISSO 在生成评论区的时候,如果在上面设置了 issoCss 为 true,则会调用你配置的 ISSO 服务内部的资源。
具体来说就是 docker 内的这个路径 /isso/isso/css/isso.css

你可以自己将写好的 CSS 文件通过 docker cp 的方式替换掉原来的文件,重新加载后就可以使用你配置的 CSS 文件了。

指定 CSS 文件资源

ISSO 支持手动指定 CSS 的源路径。

你可以在 Hexo 的 source 文件夹下面创建一个 isso.css 的文件
例如我们这里指定 source/css/isso.css

1
2
$ mkdir -p source/css
$ touch source/css/isso.css

原始 CSS 的样板可以参考 官方 Github

在上文介绍过的 themes/next/source/js/third-party/comments/isso.js 内修改部分的字段以添加部分引用

themes/next/source/js/third-party/comments/isso.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* global NexT, CONFIG */

document.addEventListener('page:loaded', () => {
if (!CONFIG.page.comments) return;

NexT.utils.loadComments('#isso-thread')
.then(() => NexT.utils.getScript(`${CONFIG.isso}js/embed.min.js`, {
attributes: {
dataset: {
isso: `${CONFIG.isso}`,
issoCss: true,
/* 主要是下面这选项 */
issoCssUrl: "/css/isso.css"
},
},
parentNode: document.querySelector('#isso-thread')
}));
});

设置完成后重新部署就能用上了。
Enjoy ~