hexo(4)安装评论功能

2022-11-17 更新

今天发现博客的评论功能忽然失效了，发现是版本更新的问题。之前一直都是引用的最新的 waline 代码，现在改成引入固定版本的 waline 代码了。

在themes/maupassant/layout/_partial/comments.pug文件中修改如下代码：

这一行代码：

Copy
script(src='//unpkg.com/@waline/client@v2/dist/waline.js')

替换为：

Copy
script(src='//unpkg.com/@waline/client@v2.12/dist/waline.js')

前提

带有 docker 环境的服务器

会使用 docker-compose、postgres 和 caddy

这里我们采用 docker + waline + postgres + caddy 来自搭部署评论系统，详细细节可以参考waline 官网。

配置 postgres 数据库

提示：如果你没有数据库，也可以使用系统自带的 sqlite 数据库来部署。

先查看下官方多数据库服务支持文档中的 postgres 数据库支持，需要先创建好表和表结构。

在https://github.com/walinejs/waline/blob/main/assets/waline.pgsql中，直接复制内容到 postgres 命令行中运行即可创建成功，这里我用的是 pgAdmin（postgres 的管理工具）。

如果打不开官网，也可以复制下面的内容的直接到数据库命令行中回车即可。

Copy
CREATE SEQUENCE wl_comment_seq;

CREATE TABLE wl_comment (
id int check (id > 0) NOT NULL DEFAULT NEXTVAL ('wl_comment_seq'),
user_id int DEFAULT NULL,
comment text,
insertedAt timestamp(0) without time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,
ip varchar(100) DEFAULT '',
link varchar(255) DEFAULT NULL,
mail varchar(255) DEFAULT NULL,
nick varchar(255) DEFAULT NULL,
pid int DEFAULT NULL,
rid int DEFAULT NULL,
sticky boolean DEFAULT NULL,
status varchar(50) NOT NULL DEFAULT '',
"like" int DEFAULT NULL,
ua text,
url varchar(255) DEFAULT NULL,
createdAt timestamp(0) without time zone NULL DEFAULT CURRENT_TIMESTAMP,
updatedAt timestamp(0) without time zone NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) ;

CREATE SEQUENCE wl_counter_seq;

CREATE TABLE wl_counter (
id int check (id > 0) NOT NULL DEFAULT NEXTVAL ('wl_counter_seq'),
time int DEFAULT NULL,
url varchar(255) NOT NULL DEFAULT '',
createdAt timestamp(0) without time zone NULL DEFAULT CURRENT_TIMESTAMP,
updatedAt timestamp(0) without time zone NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) ;

CREATE SEQUENCE wl_users_seq;

CREATE TABLE wl_users (
id int check (id > 0) NOT NULL DEFAULT NEXTVAL ('wl_users_seq'),
display_name varchar(255) NOT NULL DEFAULT '',
email varchar(255) NOT NULL DEFAULT '',
password varchar(255) NOT NULL DEFAULT '',
type varchar(50) NOT NULL DEFAULT '',
label varchar(255) DEFAULT NULL,
url varchar(255) DEFAULT NULL,
avatar varchar(255) DEFAULT NULL,
github varchar(255) DEFAULT NULL,
twitter varchar(255) DEFAULT NULL,
facebook varchar(255) DEFAULT NULL,
google varchar(255) DEFAULT NULL,
weibo varchar(255) DEFAULT NULL,
qq varchar(255) DEFAULT NULL,
"2fa" varchar(32) DEFAULT NULL,
createdAt timestamp(0) without time zone NULL DEFAULT CURRENT_TIMESTAMP,
updatedAt timestamp(0) without time zone NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) ;

具体创建表流程如下：

docker 部署 waline

在适当的位置新建docker-compose.yml文件，内容如下：

Copy
# docker-compose.yml

version: '3'

services:

waline:

container_name: waline

image: lizheming/waline:latest

restart: unless-stopped

ports:

- 9015:8360 # 前面9015的端口号可以任意修改，与其他应用不冲突即可

environment:

TZ: 'Asia/Shanghai'

SITE_NAME: "菜小牛的博客"

SITE_URL: 'https://cirry.cn' # 网站网址

SECURE_DOMAINS: 'cirry.cn' # 域名

AUTHOR_EMAIL: 'cirry6@aliyun.com' # 邮箱

PG_HOST: ******.cirry.fun # 数据库地址，请填写自己的数据库地址

PG_PORT: 5432 # 数据库端口，postgres默认端口号为5432

PG_DB: hexo # 数据库名

PG_USER: ****** # 数据库用户，请填写自己的用户名

PG_PASSWORD: ****** # 数据库密码，请填写自己的密码

配置 Caddy

将搭建好的暴露端口为 9015 的 waline 服务，通过 caddy 反代和添加 ssl 加密。

Copy
# Caddyfile
# 配置自己的网址，每个人配置不一样，请勿直接复制
https://waline.cirry.cn:66666 {

reverse_proxy localhost:9015

}

配置主题

在_config.maupassant.yml中，修改如下内容即可：

Copy
waline: ## See: https://waline.js.org/
enable: true ## If you want to use Waline comment system, please set the value to true.
serverURL: https://waline.cirry.cn:66666 ## Your server url, e.g. https://your-domain.vercel.app
pageSize: 10 ## The desired number of comments shown in each page.

至此，评论功能已经完全自搭在自己的服务器上了，清除缓存，重新运行后，样式如下：

开启侧边栏最近评论功能

虽然在_config.maupassant.yml中的配置项里，有开启最近评论功能，但是配置完成后并没有显示样式。

Copy
widgets: ## Seven widgets in sidebar provided: search, info, category, tag, recent_posts, recent_comments and links.
- search
- info
- category
- tag
- recent_posts
- recent_comments # 挂载最近评论功能
- links

在themes/maupassant/layout/_widget/recent_comments.pug下，我们可以看到主题默认只配置了disqus的最近评论功能，所以接下来，我们自己编写我们的自己的waline最近评论功能。

Copy
if theme.disqus.enable == true
.widget
.widget-title
i.fa.fa-comment-o= ' ' + __('recent_comments')
script(type='text/javascript', src='//' + theme.disqus.shortname + '.disqus.com/recent_comments_widget.js?num_items=5&hide_avatars=1&avatar_size=32&excerpt_length=20&hide_mods=1')

第一步，在_config.maupassant.yml中新增配置项：

Copy
waline: ## See: https://waline.js.org/
enable: true ## If you want to use Waline comment system, please set the value to true.
serverURL: https://************ ## Your server url, e.g. https://your-domain.vercel.app
pageSize: 20 ## The desired number of comments shown in each page.
wordLimit: 500 ## Limit input word count, 0 means no limit
requiredMeta: ['nick','mail'] ## required user information e.g. ['nick','mail','link']
count: 6 ## The number of recent comments,default. 10

第二步：在themes/maupassant/layout/_widget/recent_comments.pug 中，修改内容如下：

Copy
if theme.disqus.enable == true
.widget
.widget-title
i.fa.fa-comment-o= ' ' + __('recent_comments')
script(type='text/javascript', src='//' + theme.disqus.shortname + '.disqus.com/recent_comments_widget.js?num_items=5&hide_avatars=1&avatar_size=32&excerpt_length=20&hide_mods=1')

if theme.waline.enable == true
.widget
.widget-title
i.fa.fa-comment-o= ' ' + __('recent_comments')
#widget-waline-list
script(type='text/javascript', id="recent-comment", serverURL=theme.waline.serverURL, count=theme.waline.count , src=url_for(theme.js) + '/recent-comments.js' + '?v=' + theme.version, async)

第三步：这里涉及到发送请求，所以我们先需要在themes/maupassant/source/js/目录下，创建 js 文件recent-comments.js。

填写recent-comments.js内容如下：

Copy
!function () {
let serverURL = document.getElementById("recent-comment").getAttribute("serverURL")
let count = document.getElementById("recent-comment").getAttribute("count")
if (!count) {
count = 10
}

//格式化时间
function format( date ) {
return new Date(date).toLocaleString()
}

// 处理评论
function dealComment( commentStr ) {
let re = /<a[^>]*href=['"]([^\\"]*)['"][^>]*>(.*?)<\/a>/g;
let arr = [];
while (re.exec(commentStr) != null) {
arr.push(RegExp.$1); //如果是RegExp.$1那么匹配的就是href里的属性了!
arr.push(RegExp.$2)
}
if (arr.length > 0) { // 说明有匹配到回复
commentStr = commentStr.replace(/<a[^>](.*?)<\/a>/, arr[1])
return {
href: arr[0],
author: arr[1],
str: commentStr
}
}
return ''
}

$.ajax({
url: serverURL + '/comment?type=recent',
dataType: 'json',
data: {
count
},
success: function ( response ) {
let comments = ' '
response.forEach(( comment, index ) => {
comments += ' ' + (index + 1) + '、 ' + format(comment.insertedAt)
if (comment.pid) {
let {href, author, str} = dealComment(comment.comment)
comments += ' '+ str + ' '
} else {
comments += ' ' + comment.comment + ' '
}
comments += ' ' + '--' + comment.nick + ' '
})
comments += ' '
$('#widget-waline-list').append(comments)
},
})
}()

这里涉及到了waline提供的获取最近评论接口，在这里查看waline 提供的 api。

第四步：调整样式

这一步只是针对，有人在评论中填入了 emoji 表情，emoji 会显示很大，我们在themes/maupassant/source/css/style.scss中定位样式，具体位置如下：

在#sidebar --> .widget --> ul --> li下新增如下代码即可。

Copy
.wl-emoji{
width: 16px;
}

最后，在themes/maupassant/source/css/style.scss中末尾追加如下样式：

Copy
/* recent-comments waline style*/
.waline-comment-content {
padding: 6px;
background-color: #f8f8f8;
border-radius: 6px;
overflow: auto;

p {
margin: 0;
display : -webkit-box;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2; /*这里设置第几行显示省略号，可以设置第一行或者其他行*/
}
}

.waline-comment-content-author {
text-align: end;
margin-bottom: 6px;
}

开启字数限制和禁用匿名

在themes/maupassant/layout/_partial/comments.pug中找到waline.init方法，在方法中添加一个配置项即可。

Copy
Waline.init({
el: '#waline',
comment: true,
serverURL: '#{theme.waline.serverURL}',
pageSize: '#{theme.waline.pageSize}',
wordLimit: 300,
requiredMeta:['nick', 'mail'],
})

提示：waline 有自带的垃圾信息过滤功能，但是还是限制一下访客输入比较好，防止有人恶意操作。

开启邮件提醒

这里我直接使用QQEmail做邮件服务商了。

在docker-compose.yml中的environment里添加如下邮件服务商配置信息：

Copy
SMTP_HOST: "smtp.qq.com"

SMTP_PORT: 465

SMTP_USER: "你的qq邮箱"

SMTP_PASS: "qq邮箱提供的授权码"

SMTP_SECURE: "true"

提示：qq 邮箱的授权码在登录qq邮箱之后 --> 设置 --> 账户 --> 生成授权码中获得。

waline 也有统计阅读次数的功能，前面已经使用了不蒜子，这里就不重复讲，如果后期不蒜子不好用，可能会切换到这个上。

本文需要的一些知识比较多，如果有不明白的，可以留言，我可以针对性的写个详细的文章。

页面关闭评论功能

如果你在类似关于我或者历史这样的页面中，不希望有评论功能，在对应的文档中的front matter中设置comments: false即可。