前两天把博客文章从 Typecho 迁移到 Hugo,光是设置 Front Matter 参数和重新配置图片链接就费了很大功夫。
一个博客的价值,首先是文章,紧接着就是评论。评论证明博客在互联网和真实世界产生的影响,承载了人与人之间的交互关系。私心一点地说,五湖四海的评论是重要的回忆,是构成“我”的一部分。
所以,将原站评论 copy 到新站的对应文章下是很有必要的。
配置 Waline
相比于 Wordpress、Typecho 等动态博客,静态博客只能外挂评论系统,选择众多,各有优劣。在参考了这篇文章和查阅各个评论系统官网后,我最终选择Waline。
Waline 的中文文档内容翔实,设置LeanCloud数据库和Vercel 服务端后即可进入评论管理后台 https://<你的服务端域名>/ui/ 。首次注册成为管理员,在这里可以管理评论和用户。
导出 Typecho 评论
Typecho 太老了,用户少,不如 Hexo、Wordpress 等社区活跃,互联网上资料也很少。
笔者仅找到大佬怡红院落写的一个 Typecho 导出评论到 Valine 的插件 Export2Valine(也是 Waline 文档中的)。
但上次更新是三年前,经测试已经失效,仅能导入第一条评论。查看导出的 jsonl 文件,显然评论数据都已经完全导出。
先将该插件安装到 Typecho (注意更改插件文件夹名称为 “Export2Valine” !)。
参考这一篇 Typecho 迁移到 Hexo 的文章,该插件年久失修,需要作一些更改。
找到插件文件夹下的 Action.php ,第 42 行开始改成如下代码(追踪父评论):
$arr = array(
"objectId" => $comment["coid"],
"QQAvatar" => "",
"comment" => $comment["text"],
"insertedAt" => array(
"__type" => "Date",
"iso" => $time
),
"createdAt" => $time,
"updatedAt" => $time,
"ip" => $comment["ip"],
"link" => $comment["url"],
"mail" => $comment["mail"],
"nick" => $comment["author"],
"ua" => $comment["agent"],
"url" => "/{$slug}.html"
);
if($comment["parent"]) {
$arr["pid"] = $comment["parent"];
$arr["rid"] = $this->getRootId($comment["coid"]);
}
其他部分不用修改。
接着在 Typecho 后台-控制台-评论导出,打开下载的 jsonl 文件,删除开头的 #filetype:JSON-streaming {"type":"Class","class":"Comment"}\n\n 。
保存后关闭文件,将文件拓展名改为 .json 。
修正 json 格式
导出文件 jsonl 内中文都用转义,只有一行,看起来一团乱麻。
为转化成便于阅读、编辑与导入的 json 格式,我们先利用编辑器的查找与替换功能,将 }\n{ 替换为
},
{
Xcode 的替换,换行符可以点击左侧小放大镜标选择插入。
此时每行一个评论对象。
同样,将各个评论对象内的字段结构分开,将 "," 替换为
",
"
此时,我们可以看出每个评论对象内包含多个数据,形似
{"objectId":"3",
"QQAvatar":"",
"comment":"\u6d4b\u8bd5\u4e00\u4e0b",
"insertedAt":{"__type":"Date",
"iso":"2023-06-27T09:37:07.000Z"},"createdAt":"2023-06-27T09:37:07.000Z",
"updatedAt":"2023-06-27T09:37:07.000Z",
"ip":"223.104.150.16",
"link":**null**,"mail":"2868301418@qq.com",
"nick":"2868301418",
"ua":"Mozilla\/5.0 (Linux; Android 13; V2171A Build\/TP1A.220624.014; wv) AppleWebKit\/537.36 (KHTML, like Gecko) Version\/4.0 Chrome\/109.0.5414.86 MQQBrowser\/6.2 TBS\/046605 Mobile Safari\/537.36 V1_AND_SQ_8.9.63_4190_HDBM_T QQ\/8.9.63.11380 NetType\/4G WebP\/0.3.0 Ap",
"url":"\/\u4ea4\u53cb\u6807\u51c6-\u548c\u5e73\u5171\u5904\u4e94\u9879\u539f\u5219.html"},
{"objectId":"4",
"QQAvatar":"",
"comment":"\u600e\u4e48ip\u4e0d\u5bf9",
"insertedAt":{"__type":"Date",
"iso":"2023-06-27T09:38:15.000Z"},"createdAt":"2023-06-27T09:38:15.000Z",
"updatedAt":"2023-06-27T09:38:15.000Z",
"ip":"223.104.150.16",
"link":**null**,"mail":"2868301418@qq.com",
"nick":"2868301418",
"ua":"Mozilla\/5.0 (Linux; Android 13; V2171A Build\/TP1A.220624.014; wv) AppleWebKit\/537.36 (KHTML, like Gecko) Version\/4.0 Chrome\/109.0.5414.86 MQQBrowser\/6.2 TBS\/046605 Mobile Safari\/537.36 V1_AND_SQ_8.9.63_4190_HDBM_T QQ\/8.9.63.11380 NetType\/4G WebP\/0.3.0 Ap",
"url":"\/\u4ea4\u53cb\u6807\u51c6-\u548c\u5e73\u5171\u5904\u4e94\u9879\u539f\u5219.html"},
公共字段说明
- objectId: 评论的唯一标识符(如 “4” 和 “5”)
- QQAvatar: QQ头像链接(当前为空字符串)
- comment: 评论内容(包含 Unicode 转义字符,如
\u600e\u4e48表示"怎么") - insertedAt/createdAt/updatedAt: 时间戳(ISO 8601 格式)
- ip: 评论者的 IP 地址
- link: 评论者提供的链接(可能为 null)
- mail: 评论者的邮箱地址
- nick: 评论者昵称
- ua: 用户代理(显示浏览器/设备信息)
- url: 被评论的页面路径
特殊字段
- pid: 父评论 ID
- rid: 根评论 ID
如果 "link" 值为 null ,则 "link" 与 "mail" 间没有换行。json 对换行不敏感,所以可以不管。
此时在文件首尾用 [ ] 将内容包裹起来,保存文件。
修改评论属性
此时可以直接导入 LeanCloud 了,但尚有内容可以修改。
Export2Valine 将评论关联文章的 url 设置为 \/slug ,比如 "url": "\/Summary-of-the-First-Semester-of-Junior-Year.html" ,其中 \/ 是转义 / 。
想要把评论与新博客的文章联系起来,需要手动修改 url 为新博客的文章链接。
以笔者该博客为例,Hugo 生成的网站根目录下有 zh-cn,zh-tw,en,ja 四个文件夹(开启了多语言),中文站的文章在 /zh-cn/post/文章分类/ 下。
笔者在本地博客源文件就将文章按分类放入不同文件夹,比如 /content/post/Thoughts/最近写的诗.md 生成网页相对地址为 zh-cn/post/thoughts/最近写的诗 。
如果你的新博客文章在根目录且名称未更改,那自然不用修改 url。
若都在 /post/ 下,可以使用查找与替换将
"url":"\/
替换为
"url":"\/post\/
笔者是暂时替换为
"url":"\/zh-cn\/post\/
同样,友链、说说之类的独立页面评论也应修改为新博客对应页面相对地址。 比如友链页面
"url":"\/links.html
替换为
"url":"\/zh-cn\/friend\/
将 post 和独立页面中可以大规模应用查找替换的 url 先替换,否则导入后难以大批量替换。
使用查找与替换时,尽量多包裹共同内容,找“最大公约数”,避免错误修改。
注意转义 \/ !!!
导入 LeanCloud
在 LeanCloud 控制台-数据存储-导入导出,选择修改好的 json 文件,Class 填写 Comment ,导入。
注意,如果你之前在博客 Waline 发过测试评论,或曾尝试过导入 Comment,Waline 会先创建 Comment Class ,再导入就无法成功导入数据(LeanCloud 会提示成功,但没有新数据导入)。
只能先在控制台-结构化数据,选择 Comment 并删除该 Class,再次尝试导入。LeanCloud 页面可能不会及时刷新结果,Ctrl+F5 刷新缓存就有了。
导入成功后,再针对每个评论 url 进行单独设置。
比如笔者的 post 需要一个个归类到 "url":"\/zh-cn\/post\/文章分类\/ 下,此时善用 LeanCloud 批量操作和按条件过滤功能。
后记
评论的整理并没有耽误笔者太长时间,120 条评论大部分是笔者自己在说说页面的自言自语,所以 url 可以批量修正。仅有的十几条他人评论分布在寥寥三五个文章中,通过 post 筛选修改起来很快。不知道是好事还是坏事呢(笑)
自言自语也好,他人的留言也好,每一条于笔者都有着非同寻常的意义,隔一段时间回看就会有新的感受。
如最开始所言,这是笔者的成长轨迹,是笔者存活于世的证明,是“我”的一部分。
而你,我亲爱的读者,是你赋予我价值。
有空的话请多多评论吧~笔者真的会开心很久的说(如果评论善意的话)。

何时一樽酒,重与细论文。