早年间博客火热的时候,大家纷纷开通了博客。不用担心没有话题可写,可以先写如何选择博客托管平台;再折腾自建博客,话题变成如何搭建和使用博客程序。2021年,我从 WordPress 切换到 Grav 之后,竟然还没有写过关于 Grav 的内容,这个话题还没有充分探讨。鉴于我的输出频率实在太低,还没到不开发个博客就没话题的程度,那么为什么还要重新写博客程序呢?

WordPress

最早的时候就在用 WordPress,后来尝试过 Typecho,再后来各种基于 Markdown 文本文件的静态博客程序开始流行,厌烦 WordPress 的臃肿之后,我谨慎地选择了非静态的 Grav。WordPress 等程序依赖数据库来管理内容,这就导致:

  • 难以用 Git 来做版本控制
  • 需要写大量代码来支持在原有数据库上扩展自定义内容类型
  • 难以完整地迁移数据
  • 严重依赖程序本身提供的管理 UI

而基于文本的则完全没有这些问题。所有的内容都在 Git Repo 中;内容结构随便写;迁移程序时文本结构无需删减;可以使用任何文本编辑工具管理。生成式的静态博客甚至连主机也不需要,扔到各种 Pages 类托管服务上即可。不过也存在一些缺点,比如缺失一些动态功能,需要引入第三方评论系统。毕竟一个纯静态的站点,要实现任何动态的功能,还是额外需要一个后端服务器的。

Grav

所以,基于 PHP、文本的 Grav 成为了一个非常好的选择。Grav 非常强大,比如

  • 使用 Yaml 文件定义蓝图,可随意定制内容类型
  • 提供了大量内置方法,比如在主题模板中随意加工图片
  • 支持多站点模式
  • 合理而强大的多语言支持
  • 提供管理面板,有根据蓝图自动生成的页面表单

除了个人站点之外,我还使用 Grav 做过公司官网、信息收集站、工作室站点、商城等多个网站。但在使用过程中,有一些奇怪的体验:

  • 默认情况下,路由是基于文件系统的(也可以在单篇内容中另行指定),可能会发生数百个文章挤在同一个目录的情况,体验非常糟糕
  • 没有使用标准的 URL 参数,比如分页地址不是 /?page=1 也不是 /page/1,而是 /page:1
  • 管理 UI 中一些操作非常不便,比如在博客目录下新建内容,需要单独指定这篇内容的类型是「博客文章」
  • 访问管理 UI 时会同步检查程序与插件的更新,不过其服务器却非常缓慢,也未提供关闭检查和指定镜像的功能
  • 一些基础插件迭代慢,依赖过多,这导致几乎无法摆脱 jQuery
  • 某些方便的插件还不够完善,比如官方的评论插件不支持嵌套评论
  • 多语言仅针对文章内容,系统设置只能多个语言共用一套

Press

于是我终于自己做了一个,姑且先叫做 Press。

前端技术日新月异,越变越爽,难免要用一下;内容管理系统嘛,自然要考虑支持 SSR 和静态生成。最终我选择了 SvelteKit。其实用 SvelteKit 比较难做出像 WordPress 和 Grav 这种通用的内容管理系统,不过我的个人网站和一些项目基本都需要做各种定制,索性就把 Press 定义成脚手架吧。

关于使用 Svelte 搭建博客,已经有很多文章探讨过。既然是重新开发,我有一些舍本逐末的设计,需要做一些额外的工作来实现。比如,遵循 Svelte 的文件系统路由的同时,实现文章目录分组支持,附件路径与文章路径一致。举个例子,某篇文章的路径是 pages/(article)/(2023)/article-a/item.zh_CN.md,那么它的链接就是 /article-a,这部分是不限制目录层级的,完全取决于目录结构。同时有一张图片 pages/(article)/(2023)/article-a/a.png,那么我希望它的链接是 /article-a/a.png,这在 SvelteKit 里只能通过 hooks 重新做路由来实现。

在 WordPress 时代,很多人用插件折腾来折腾去,比如在 RSS 中添加相关文章、推荐评论。现在用自己的博客程序,各种变态的需求都无需插件了(都自己苦哈哈地手动实现),简直神清气爽!

目前还在初步的开发阶段,预计这个话题足够写个一年半载,再也不愁没话题了(偷懒得另找借口了)。