Hexo Cactus主题实现支持Waline评论系统

Cactus 主题暂未集成对 Waline 的支持:https://github.com/probberechts/hexo-theme-cactus/issues/343 ,Cactus 作者提示可以自己实现,将 Waline 评论系统集成到 Cactus 主题中,参考:https://github.com/probberechts/hexo-theme-cactus/pull/54/commits

实现 Waline 评论支持需要修改如下文件:

1
2
3
themes\cactus\layout\_partial\comments.ejs
themes\cactus\layout\_partial\head.ejs
themes\cactus\layout\_partial\scripts.ejs

支持 Waline

在 Cactus 主题中,可以通过 themes\cactus\_config.yml 开启并配置 Waline:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# themes\cactus\_config.yml

waline:
enabled: true # 是否开启
serverURL: 'https://xxx.vercel.app' # Waline Vercel服务端地址,替换为自己的服务端地址
avatar: mm # 头像风格
meta: [nick, mail] # 自定义评论框上面的三个输入框的内容
pageSize: 10 # 评论数量多少时显示分页
lang: zh-CN # 语言, 可选值: en, zh-CN
# Warning: 不要同时启用 `waline.visitor` 以及 `leancloud_visitors`.
visitor: false # 文章阅读统计
comment_count: true # 如果为 false , 评论数量只会在当前评论页面显示, 主页则不显示
requiredFields: [nick, mail] # 设置用户评论时必填的信息,[nick,mail]: [nick] | [nick, mail]
emoji: //unpkg.com/@waline/emojis@1.2.0/qq
dark: true

配置文件的属性可以参考:https://waline.js.org/reference/client/props.html

接下来修改 themes\cactus\layout_partial\comments.ejs 支持 Waline:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- themes\cactus\layout\_partial\comments.ejs -->

<% if(page.comments && theme.disqus.enabled){ %>
<div class="blog-post-comments">
<div id="disqus_thread">
<noscript><%= __('comments.no_js') %></noscript>
</div>
</div>
<% } %>
<% if(page.comments && theme.utterances.enabled){ %>
<div class="blog-post-comments">
<div id="utterances_thread">
<noscript><%= __('comments.no_js') %></noscript>
</div>
</div>
<% } %>
<% if(page.comments && theme.waline && theme.waline.enabled){ %>
<div class="blog-post-comments">
<div id="waline_thread"></div>
</div>
<% } %>

page.comments 表示当前页面是否支持评论,在文章前面设置,Cactus 主题默认在文章中开启,在其他页面中关闭;

1
2
3
4
5
6
7
8
title: Tags and Categories
date: 2017-12-24 23:29:53
tags:
- Foo
- Bar
categories:
- Baz
comments: true

theme.waline.enabled 表示 Waline 评论是否启用。如果页面支持评论并且启用 Waline 评论系统,那么就向网页中插入如下 html 代码:

1
2
3
<div class="blog-post-comments">
<div id="waline_thread"></div>
</div>

其中 waline_thread 在后续初始化 Waline 时会用到。

引入 Waline

首先需要在 Cactus 主题的代码中引入 Waline,参考:https://waline.js.org/guide/get-started/#html-%E5%BC%95%E5%85%A5-%E5%AE%A2%E6%88%B7%E7%AB%AF 。主要是从外部引入 waline.css 和 waline.mjs 这两个文件。

引入 waline.css

在 themes\cactus\layout_partial\head.ejs 文件中引入 waline.css,head.ejs 可以向网页 html 的 <head> 元素中注入代码:

1
2
3
4
5
6
7
8
9
10
11
<!-- themes\cactus\layout\_partial\head.ejs -->

<head>

···

<!-- Waline Comments -->
<% if (theme.waline.enabled){ %>
<link rel="stylesheet" href="https://unpkg.com/@waline/client@v2/dist/waline.css"/>
<% } %>
</head>

通过 <link>元素从外部引入 waline.css 。

引入 waline.mjs

在 themes\cactus\layout\_partial\scripts.ejs 文件中引入 waline.mjs,scripts.ejs 可以向网页中注入javascript代码:

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
<!-- themes\cactus\layout\_partial\scripts.ejs -->

···

<!-- Waline Comments -->
<% if (theme.waline.enabled){ %>
<script type="module">
import { init } from 'https://unpkg.com/@waline/client@v2/dist/waline.mjs';

var EMOJI = ['//unpkg.com/@waline/emojis@1.2.0/weibo']
var META = ['nick', 'mail', 'link'];
var REQUIREDFIELDS = ['nick', 'mail', 'link'];

var emoji = '<%= theme.waline.emoji %>'.split(',').filter(function(item){
return item !== ''; // filter()返回满足不为空item
});
emoji = emoji.length == 0 ? EMOJI : emoji;

var meta = '<%= theme.waline.meta %>'.split(',').filter(function(item){
return META.indexOf(item) > -1; // filter()返回满足META.indexOf(item) > -1为true的item
});
meta = meta.length == 0 ? META : meta;

var requiredFields = '<%= theme.waline.requiredFields %>'.split(',').filter(function(item){
return REQUIREDFIELDS.indexOf(item) > -1; // filter()返回满足META.indexOf(item) > -1为true的item
});
requiredFields = requiredFields.length == 0 ? REQUIREDFIELDS : requiredFields;

init({
el: '#waline_thread',
serverURL: '<%= theme.waline.serverURL %>', // Waline 的服务端地址
path: '<%= theme.waline.path %>' == '' ? window.location.pathname : '<%= theme.waline.path %>', // 当前文章页路径,用于区分不同的文章页,以保证正确读取该文章页下的评论列表
lang: '<%= theme.waline.lang %>' == '' ? 'zh-CN' : '<%= theme.waline.lang %>', // 多语言支持,未设置默认英文
emoji: emoji,
dark: '<%= theme.waline.dark %>', // 暗黑模式适配
commentSorting: '<%= theme.waline.commentSorting %>' == '' ? 'latest' : '<%= theme.waline.commentSorting %>', // 评论列表排序方式
meta: meta, // 评论者相关属性
requiredFields: requiredFields, // 设置必填项,默认匿名
login: '<%= theme.waline.login %>', // 登录模式状态
wordLimit: '<%= theme.waline.wordLimit %>', // 评论字数限制
pageSize: '<%= theme.waline.pageSize %>' == '' ? 10 : '<%= theme.waline.pageSize %>', // 评论列表分页,每页条数
imageUploader: '<%= theme.waline.imageUploader %>', // 自定义图片上传方法
highlighter: '<%= theme.waline.highlighter %>', // 代码高亮
placeholder: '<%= theme.waline.placeholder %>',
avatar: '<%= theme.waline.avatar %>',
visitor: '<%= theme.waline.visitor %>',
comment_count: '<%= theme.waline.comment_count %>',
});
</script>
<% } %>

通过 import 从外部引入 waline.mjs 的 init 函数,并使用 init 从主题配置文件中获取配置用于初始化 Waline。初始化配置参考:https://waline.js.org/reference/client/props.html 。上述代码中的 el: ‘#waline_thread’ 就是之前在 comments.ejs 文件中设置的 <div> 元素的 id。

总结

上述文件都修改完成之后就可以重新 hexo g 生成静态网页,并执行 hexo s 本地查看。效果如下:

image-20231009113252832

注意:如果代码出现 bug 或者配置不正确,都会导致 Waline 不显示,并且 hexo 不一定会报错,需要仔细检查并手动调试排错。

如果生成的静态页面背景颜色未改变,可以先执行hexo clean操作,再hexo g重新生成。

未解决的问题

Cactus 主题支持多种配色,主要分为黑白两种模式。Waline 主题也支持黑白两种配色,通过在配置文件中设置 dark: true 来跟随主题颜色改变评论系统的配色,其主要的实现方法是在 html 中注入 style 元素动态修改评论系统的 css 属性,其中 true 就是配置文件中的 dark 属性的值:

1
<style id="waline-darkmode">true{--waline-white:#000;--waline-light-grey:#666;--waline-dark-grey:#999;--waline-color:#888;--waline-bgcolor:#1e1e1e;--waline-bgcolor-light:#272727;--waline-bgcolor-hover: #444;--waline-border-color:#333;--waline-disable-bgcolor:#444;--waline-disable-color:#272727;--waline-bq-color:#272727;--waline-info-bgcolor:#272727;--waline-info-color:#666}</style>

但是设置 dark: true 之后,如上代码不能使评论的颜色随主题切换,暂未解决。

Waline 默认使用白色配置,如果使用 Cactus 主题的 dark 模式,可以修改 themes\cactus\source\css\_partial\comments.styl 文件,强制将 Waline 的背景颜色修改为黑色:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.blog-post-comments
margin-top: 4rem

:root {
/* 常规颜色 */
--waline-white: #000 !important;
--waline-light-grey: #666 !important;
--waline-dark-grey: #999 !important;

/* 布局颜色 */
--waline-color: #888 !important;
--waline-bgcolor: #1e1e1e !important;
--waline-bgcolor-light: #272727 !important;
--waline-border-color: #333 !important;
--waline-disable-bgcolor: #444 !important;
--waline-disable-color: #272727 !important;

/* 特殊颜色 */
--waline-bq-color: #272727 !important;

/* 其他颜色 */
--waline-info-bgcolor: #272727 !important;
--waline-info-color: #666 !important;
}

自定义样式参考:https://waline.js.org/reference/client/style.html 。修改完效果如下: