从 WordPress 搬迁到 11ty

扬帆起航。

愿意讲讲为啥么?

Solidot 2024 年 12 月 17 日电:WordPress 开源项目联合创始人 Matt Mullenweg 此前在声称属于其个人的网站 WordPress.org 的登陆页面专门加入了一个选项“I am not affiliated with WP Engine in any way, financially or otherwise”,要求用户声明与 WP Engine 没有任何隶属关系。上周二,美国加州地方法庭裁决,Automattic 必须停止阻止 WP Engine 访问 WordPress.org 上的资源,以及停止干扰该公司的 WP 插件,删除 WordPress.org 登陆页面的相关复选框。Matt Mullenweg 遵守了法庭要求,但将其改成了“Pineapple is delicious on pizza” ,截至本周二,该选项仍然存在。用户如果不勾选该复选框,将会返回重试的错误信息。https://www.solidot.org/story?sid=80071

WordPress 最近的鸡飞狗跳虽然并不影响我作为终端用户继续使用,但是 Mullenweg 通过非常没品的方式继续煽风点火实在是不应该。正好我也已经厌倦了写 PHP, 所以这把我想下定决心迁移到其他博客实现。

大迁移

「程序员写博客最终会变成写博客」这句调侃最终也在我身上应验了。但自己写一个 CMS 框架实在是太心累,所以还是决定使用静态站点生成器来完成任务。挑来挑去,我最终决定使用 11ty 作为核心,以 Markdown 为载体,进行一个博客的写。

导出 WordPress 文章

只有在搬家的时候,你才会意识到自己积攒了多少东西。自 2018 年到现在,原来自己已经攒了三百多篇文章了,虽然大部分都是草稿,但总归是不能直接丢啊。

WordPress 好在提供了导出站点的功能,只要进入后台页面 - 工具 - 导出,选择「导出所有内容」即可得到包含全部必要内容的 XML 文件。

转换到 Markdown

得到这个 XML 文件只是长征第一步。接下来我们要解析这个文件并把它转换到 Markdown 了。

尽管市面上已经有很多 WordPress 转 Markdown 的仓库,比如 wordpress-export-to-markdown, 但他们都有这样那样的缺陷使得它不能完全胜任这项工作。其中比较致命的缺陷包括:不导出草稿、无法处理 SyntaxHighlight 的元数据等等。

看来没法指望其他人了。考虑到之后肯定会有很多需要魔改的地方,与其在其他人的工作上修修补补,不如直接自己写写脚本硬拉来得痛快。

人生苦短,我用 Python

尽管我个人不太喜欢用 Python, 但这种「执行一次,用后即丢」的编程场景十分受用这种胶水语言。毕竟,人生苦短,我用 Python.

pE9dNRJ.jpg

总之,我受苦的成果在这里。你可以按需修改。

这个脚本会做以下工作:

这个脚本不会管图像的事情。所以如果你需要导出图像,需要自行修改脚本。事实上你肯定需要自行修改脚本,因为 in_file 是写死的,你需要把它改成你的导出文件名才行。

移植主题

或者说,我和 11ty 搏斗的日子。

关于 11ty 以及 markdown-it 我想谈的有很多,但这里限于篇幅就只能讲一下大概的过程了。11ty 是一个多模版静态网站生成工具,也就是说,你输入的 Markdown 文件也好,HTML 也罢,实际上都被 11ty 视作一个模版。利用文件头信息,你可以实现页面嵌套、多页面生成,借助合适的模版语言,你可以实现按条件生成和循环遍历操作。如果你有更高级的需求,11ty 也支持你直接使用 JavaScript 编程来控制页面生成的过程。

移植主题也就意味着我需要把 Adams 的源代码通读一遍,然后用 11ty 实现原本用 PHP 实现的逻辑。换句话说,我得把我需要用到的 WordPress 功能在 11ty 里面实现出来。

嘿嘿,结果是实际上没多难。一开始的时候搞清楚 11ty 的逻辑花了不少时间;不过一旦你成功地学会如何说服 11ty 去做你需要的事情之后,搞各种好玩的操作就很简单了。在重新实现 WordPress 的过程中我甚至可以实现根据页面实际用到的内容来加载 JavaScript 这种在 WordPress 下难以实现的操作。虽然替换短码还是比较烦人,但移植我的按键短码插件和翻译插件也只用了一下午的时间。

这个过程中最有意思的还是爆改 markdown-it 给他加各种新奇的语法。借助 dalao 们写好的拓展插件,添加短码或者块比给 WordPress 写插件来得快得多。

设置重定向

因为在移植主题的过程中,我刻意仿照了原来 WordPress 的 URL 格式,所以重定向实际上很简单:

root /var/www/html/blag/;

location / {
    try_files $uri $uri/ $uri.html $uri/index.html =404;
}

以及更旧版的 WordPress 查询串也要一并处理:

if ($query_string ~ p=(.*)) {
  return 301 https://blag.dsstudio.tech/archives/$1.html;
}

if ($query_string ~ tag=(.*)) {
  return 301 https://blag.dsstudio.tech/special/tags/$1/;
}

不过细捋之下实际上还有很多需要处理的点,比如现在还没有实现根据年月日获取文章列表。这些增量式改进在后面详细讨论如何让 11ty 干活的时候会再实现。

评论区

尽管技术上来说,11ty 是一个静态站点生成器,但是作为博客,评论区还是要有的。哪怕一年到头没几个人留言,总归是个念想。

Isso 是一个可自托管的评论服务器。和 Disqus 差不多,但是你完全掌握所有数据。而且它还支持导入 WordPress 的评论数据,所以顺理成章接入。

不过由于 URL 有所变化,直接简单接入 Isso 会导致找不到历史评论。所以额外需要自行写一个评论区拉取原有的评论。

搜索

静态站点的搜索是一个老大难。尽管技术上来说,这种事情应该交给搜索引擎完成,但是即使 Google 也没有完整索引我之前博客的所有内容;其他搜索引擎的索引率就更低了。所以还是得自己来。

但是自己来的话,就会遇到很尴尬的场景:大部分静态搜索引擎对于中文的支持并不好。中文分词一直是一个比较困难的课题,这也是没办法的事情。好在能凑合,那就直接用 PageFind 凑合一下了。

现在的搜索是基于 PageFind 的。简单尝试了一下,其实也没有那么不堪,作为一个粗搜索而言完全够用。

机读信息

除了和人交互的内容,一些和机器交互的内容也必不可少。

RSS

11ty 提供现成的 RSS 插件,只需要直接安装并调用即可。

站点地图

站点地图并没有现成的插件可用,但是我们可以直接通过 11ty 生成站点地图。其结构如下:

---
permalink: /sitemap.xml
eleventyExcludeFromCollections: true
---

<?xml version="1.0" encoding="utf-8" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  {% for page in collections.published %}
    <url>
      <loc>https://example.com{{ page.url }}</loc>
      <lastmod>{{ page.date | date: '%Y-%m-%dT%H:%M:%S' }}</lastmod>
    </url>
  {% endfor %}
</urlset>

实际上非常简单。

所以?

站点完全静态化的最大好处就是这个玩意可以直接全部扔到 CDN 上面,以及基本不需要操心更新插件或者更新 CMS. 这比之前 WordPress 搞伪静态好多了。

蛮好,收工!

正在加载评论……

发表评论

您的评论将由管理员审核后方可公开显示。

Your comments will be submitted to a human moderator and will only be shown publicly after approval.