Hexo博客接入Waline评论系统

几个月之前将博客的评论系统从 utterances 切换到了 giscus,因为 giscus 可以准确回复某一条评论,而在 utterances 中只能新建评论然后引用别人的评论进行回复。

最近在博友的提醒下发现了 giscus 的一个痛点,那就是新增评论或者回复的时候,会导致讨论里的所有人都收到通知,不论评论是否与我相关,这有点莫名其妙。

今天某个博客里面看到 waline 评论,感觉还不错。虽说需要自己部署后端服务,但是有 Vercel 的免费服务足够使用了,于是决定将评论系统切换到 waline。

没有找到迁移 giscus 数据的方法,历史数据暂时先放弃。

由于博客主题本身没有接入 waline,所以只能从 0 开始,大概记录一下流程和遇到的问题。

部署 Waline 后端服务

按照官方 手把手教程,使用 Vercel 进行部署,非常简单,草履虫都没问题。

增加主题配置项

新增配置项:

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
waline:
enabled: true
server_url: https://my-waline.my-domain.com
# lang: "zh-CN"
dark: html.theme--dark
avatar: "mm"
meta:
- nick
- mail
- link
required_meta:
- nick
word_limit: 400
page_size: 15
reaction:
- https://unpkg.com/@waline/emojis@1.4.0/weibo/weibo_love.png
- https://unpkg.com/@waline/emojis@1.4.0/weibo/weibo_clap.png
- https://unpkg.com/@waline/emojis@1.4.0/weibo/weibo_laugh.png
- https://unpkg.com/@waline/emojis@1.4.0/weibo/weibo_hufen.png
- https://unpkg.com/@waline/emojis@1.4.0/weibo/weibo_confused.png
- https://unpkg.com/@waline/emojis@1.4.0/weibo/weibo_no_idea.png
- https://unpkg.com/@waline/emojis@1.4.0/weibo/weibo_bye.png
emoji:
- //unpkg.com/@waline/emojis@1.4.0/weibo
- //unpkg.com/@waline/emojis@1.4.0/tw-emoji
- //unpkg.com/@waline/emojis@1.4.0/tieba
- //unpkg.com/@waline/emojis@1.4.0/bilibili
- //unpkg.com/@waline/emojis@1.4.0/soul-emoji
no_copyright: true
no_rss: true

这里遇到个在 yaml 里配置数组,ejs 文件中如何引用的问题,因为直接写 config_item: ['a', 'b'] 的话,使用 <%= theme.config_item %> 获取到是一个转义之后的字符串。配置值需要按 yaml 短横线列表的方式写:

1
2
3
config_item:
- a
- b

然后在 ejs 文件中使用 var configItem = '<%- theme.config_item %>' 避免转义,在 JavaScript 代码中 使用 configItem.split(',') 进行使用。

ejs 文件修改

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
<!-- Waline Comments -->
<% if (page.comments && theme.waline.enabled && theme.waline.server_url) { %>
<script type="module">
var waline_server_url = '<%= theme.waline.server_url %>';
var waline_path = '<%= page.path %>';
// var waline_lang = '<%= theme.waline.lang %>';
var waline_avatar = '<%= theme.waline.avatar %>';
var waline_meta = '<%- theme.waline.meta %>';
var waline_required_meta = '<%- theme.waline.required_meta %>';
var waline_word_limit = '<%= theme.waline.word_limit %>';
var waline_page_size = '<%= theme.waline.page_size %>';
var waline_reaction = '<%- theme.waline.reaction %>';
var waline_dark = '<%- theme.waline.dark %>';
var waline_no_copyright = '<%= theme.waline.no_copyright %>';
var waline_no_rss = '<%= theme.waline.no_rss %>';
var waline_emoji = '<%- theme.waline.emoji %>';

import { init } from 'https://cdn.jsdelivr.net/npm/@waline/client@latest/dist/waline.min.js';

init({
el: '#waline_thread',
serverURL: waline_server_url,
path: waline_path,
meta: waline_meta.split(','),
requiredMeta: waline_required_meta.split(','),
// lang: waline_lang,
avatar: waline_avatar,
wordLimit: waline_word_limit,
pageSize: waline_page_size,
reaction: waline_reaction.split(','),
dark: waline_dark,
noCopyright: waline_no_copyright,
noRss: waline_no_rss,
emoji: waline_emoji.split(',')
});
</script>
<% } %>

深色主题适配

Waline 支持深色主题,常见的适配方式可以参考 自定义样式

我的主题本身不支持深色模式,深色模式是通过同时编译多套主题,使用 JavaScript 读取系统 prefers-color-scheme 变量再决定显示深色还是浅色主题实现的。具体来说我的深色样式是 class="theme--dark",因此配置值是 dark: html.theme--dark。同理,如果是 body 上添加 color-schema="dark" 的话,对应的配置应该是 body[color-schema="dark"]