很高兴我又开始折腾了。
其实从 2020 年开始,博客就做了全站的静态化。当时的背景是 “美团云” 停止了对个人开发者的服务,加上市面上的其他主机服务商对 MySQL 的定价又都很高。再考虑到应对爬虫读写数据库造成的稳定性问题,索性就把全站搞成了静态的。然而当时所做的静态化,真的就只是静态化,我寻思着我不会再更新了,自己把自己的网站 wget 爬了一遍,直接上传静态文件到 sae ,基本上也就失去了更新的能力。可是,停更的这两年还蛮想说话的,情绪没法排解,包括这期间在美团维护的大量文档,离职后也都看不到了。想想,还蛮可惜。终于决定再折腾下。

部署方案选择了 公子 推荐的 Vercel 和 GitHub 联动,如果是正在运行中的 WordPress 搬过来会非常丝滑,安装好 WordPress to Hugo Exporter 插件之后,在后台直接操作,等待几十秒后就可以拿到一个 zip 包,包含了你的全部文章和草稿。我是用了本地编辑器来屏蔽掉了草稿文件,后来再看插件的源码,发现可以直接修改 hugo-export.php 来过滤掉 draft 和 private 的文件。

1
return $wpdb->get_col("SELECT ID FROM $wpdb->posts WHERE post_status in ('publish', 'draft', 'private') AND post_type IN ('post', 'page' )");

刚才有说过,“正在运行” 中的 WordPress 系统搬过来会非常丝滑。
而我需要先搭一个 WordPress,把旧数据导入进去,才能做导出。
万幸的是,当年停站的时候,我还蛮小心,同时留下了 xml 和 sql 两套文件格式的数据备份。这样在 WordPress 后台导入遇到报错 “没有找到 WXR 文件,WXR 的版本号缺失或无效” 的时候,可以不用纠结 “降级” 的问题。直接沿用 BitNami for XAMPP 套件中的 phpMyAdmin 导 sql 就好。

下一个踩的坑是数据量过大的问题,虽然 sql 文件会比 xml 小一些,但是得益于这么多年的文章积累,数据也达到了 38MB,导入时候遇到了 near “ON” at position 25 的问题,修改了 /etc/my.cnf 的 max_allowed_packet=16M ,改到 128M,保存后重启,MYSQL 就再也没起来。报错信息是 Can’t connect to local MySQL server through socket ‘/opt/lampp/var/mysql ,查了下有人说是系统盘满了,默默的删了一堆文件,仍然不起作用,我猜是时间太晚了,电脑要强制我下线休息。第二天,重启了整套环境果然正常了。所以说,遇到问题别较真,睡一觉重启再试试。

过程中还修改过 php.ini 的 post_max_size 参数,让自己上传的文件可以大一点。不过到这里基本上就算搞定了。接下来的都是导入导出而已。就算遇到问题,也比较常规,WordPress 的用户体量,啥问题都能搜到答案。

然而把我的周日也搭进去的是 pagecookery 的迁移,相较于 800 多篇的博客来说,我竟然发了 8000 多篇微博。迁移起来相当费劲。开始想自己写一个转换工具的,算了下时间,会把自己的下个周末也搭进去,索性还是在 hugo-export.php 的基础上修改吧。最简单的方法是直接把 entry 的表,修改成 wp_post ,然后保持结构的对齐,把需要的字段补上去。这里面遇到的问题是 post_date 在 WordPress 用的是 00-00-00 的格式,然而 pagecookery 存储的是时间戳。需要写 sql 转换下。于是最坑的事情来了,我直接写了个 UPDATE wp_posts SET new_post_date = from_unixtime(post_date, ‘%Y-%m-%d %h:%i:%s’); 就志得意满的开始导出 md 文件了,结果发现有大量微博的发布时间是凌晨,我还寻思自己年轻的时候这么不养生吗?最终还是本地再搭了一套 pagecookery 来比对时间,果然,from_unixtime 整整差了 8 个小时的时差。其实这样就好 UPDATE wp_posts SET post_date_gmt = from_unixtime((post_date + 8*3600));

说到时间,再有一个问题是,我数据库里有 8000 多行,每次导出的文件却只有 2000 多,后来查了下代码,hugo-export.php 的导出方式是按照日期和文章标题来命名的,我的微博里没有文章标题,只按日期命名就导致了每天只有一篇微博被发了出来,修改 Y-m-d 为 Ymd-Hms 就可以了。

1
$filename = $this->post_folder . date('Y-m-d', strtotime($post->post_date)) . '-' . urldecode($post->post_name) . '.md';

以上,种种坎坷吧,终于是把数据都挪了过来。甚至还有时间打扫卫生、写写博客。就是这模板编辑起来很麻烦呀,缺个 md 的编辑器,自动生成个时间什么的。回头再研究。写篇微博还要坐在电脑前,略微有点反人类了。