苟日新

突然被人跑来问,是怎么做到写博客坚持这么久的,而且可以持续输出?

(荣幸地,拿起话筒:)啊,我不觉得我这个样子,叫做「持续输出」啦。早就连每月一更都不能保证了,而且那些技术相关的帖子,在我心里都不能算是「更新博客」的,用这些凑数也为我自己所不齿……

但我看到这个问题时,首先想到的,一个很重要的因素:大概是因为,这个站就一直在这儿吧~ 我的技术能力,不需要花什么额外的精力,就能让这个 blog 一直存活下去。于是,想写东西的时候,这里始终有个地方,可以让我写。

——也有很多时期,是完全写不下去的,长时期没法去面对、去反刍自己的生活;然而也没必要因此而关站,就让 blog 存活在那里,终归是个表述的出口。大概是因为,我也是希望,自己能够从那些「无法整理自己」的状态中,渐渐走出来,回复到可以写东西的状态吧。所以站点的持续存在,满重要的,因为确实能感觉到,想写点什么的时候,如果没有这么个站,又或者需要自己重新架一个,可能也就不写了……


这种「随时可以在站点写东西」的状态,也影响着对 blog 平台的选择(怎么又拐到技术贴去了?好吧,之前也一直想吐槽这方面,就顺带提一下)。这些年一直有 〖wordpress vs 各种静态博客〗哪个更好的争论。双方确实各有利弊。总体来说,静态博客最大的优点就是……省钱,可以薅 github、vercel 之类托管网站的羊毛。但另一方面,静态博客每次发布、或者修改一篇文章的过程,其实满折腾的。通常情况下,它需要

  • 一台固定的电脑,安装静态博客编译程序,并且从这台电脑发布到 github 的专门权限。而不是随便打开一台电脑或手机,从浏览器就能编辑发文;
  • 每次发文时的一系列专门操作。

我不乏看到有人,好久没有更新,突然想写一篇文章时,忘了怎么操作,翻出攻略来重温一遍;甚至忘了连接 github 的 ssh-key……可能别人觉得这样的折腾无所谓,或者自我管理优秀的话,不会出现这种情况。但我个人觉得,这是会在主观上,影响发文章的状态的。所以,随便在任何地方任何电脑上都能直观地发文,感觉还是蛮重要的。

好像也是可以通过一系列操作,实现用浏览器某个网站上编辑文章,然后自动编译发布到托管网站的。我没有仔细去关注。但是,如果把 blog 的生命周期,放到 5~10 年这个尺度上,那么这些网站之间的复杂依赖关系,很大程度上是不靠谱的。譬如我已经看到好几个静态 blog 的外挂评论系统,不知为什么不工作了……总之,相比之下,我可能更宁愿去使用那些免费带广告的 blog 平台。

我对写 blog 的新人的推荐,一直是——

  • 如果有技术能力、也有服务器的话,自建 wordpress;
  • 或者找人蹭一个。如果我们比较熟,你可以去买个域名,把 blog 挂在我的服务器上。这并不是很大的负担。(ps,个人 wordpress 小站,是可以不必安装开销很大的 mysql 数据库的);
  • 如果上面两条都不行,那么,我优先推荐去注册现成的 wordpress.com 或者 blogspot.com,目前看起来,长期靠谱的只有这两家了。虽然免费版界面不好看、还有广告,但长期写着应该没问题的;
  • 当然,我不会给乐于尝试静态博客的人泼冷水。但我会根据你的技术能力和气质,暗戳戳地担心:
    • 你能坚持写多久;
    • 你写出来的,会不会很多都是关于你怎么建站的经历和心得……

转一张,对于熟悉这十几年来 blog 平台变迁的人,应该会很搞笑:用不同工具写 blog 的人,(写 blog 文章)vs(写关于怎么配置 blog 的文章)的对比。右下角那些术语,都是在各个年代,需要各种不同程度的折腾的,静态 blog 方案:gatsby、org mode、jekyll、hugo、git workflow……


ps,两个月前,用这段代码方案,把我在 twitter 的所有 po 文,都导入到了自建的 mastodon 里。Twitter 那边,应该会随着 Elon Musk 的各种不靠谱折腾,渐渐放弃掉了吧。而每条推文的字数限制,从 twitter 的 140 字,变成 mastodon 的 500 字后,很多几百字的感受,要不要专门写到 blog 这边来,就比从前,更让人犹豫。具体怎么处理,我还没想好。

评论区

如今很多 blog,尤其是这些年新人们搭建的静态 blog,都是没有给文章留言评论的功能的。

(略过 wordpress 和 hexo、hugo 等静态引擎对比若干)
(略过静态 blog 外挂评论系统的技术难度和优劣若干)

最近读的一篇文章,让我想要和作者讨论一些感受,然而却没有评论的地方。——其实我是有作者的其它社交网络账号,甚至在聊天软件上加了好友的。但总感觉,在其它地方,另外开启一串讨论,有些违和。以及和文章的话题也有关系吧,一些和内心情绪相关的话题,反而不适合凑上前和人家私密地聊感受。文章底部的评论区,是个我觉得合适的,或者说在我的认知中习惯了的,豪猪之间的距离。

也许人家就是因为不想有这样的讨论,才不设评论区呢?
——但也许人家并不是这样想的呢?也许他在这篇文章想要有人讨论,而那篇文章则不想,而无论想或不想,和他有没有在 blog 里加评论系统,并没有任何关系。所以那些「想 or 不想」,其实都只是我自己通过臆断,试图对当前状态的一种解释。甚至再从这样的解释,为自己总结出莫须有的规律和准则。

包括我觉得「评论区更舒适」,仍然是一种非常自我的总结。如今连 blog 都没几个人写,仅有的几个用户,也是不同年代不同环境不同引擎。于是,这种自以为的总结,不可能是被很多人共鸣认可的准则。所以真的有存在的必要么?


这种纠结的心态,大概来源于,自己在日常的其它方面,被这种潜在的总结准则所扰。虽然我在反思后,是倾向于让这些准则变得不存在的;但对很多人而言,似乎仍然是存在的(这个我不觉得是臆断),并以此构建出交流的障碍。

当然,即使如此,从权力关系的角度,这也不是让我能够有了感受就可以肆无忌惮地把读后感塞给人家的理由。(这是另一种纠结了……

[php] 将多个 RSS 地址合并成一个

弄了个 php 程序,可以把自己的(or 别人的)多个 blog 的 RSS 订阅地址,合并成一个,供人订阅。例如,现在本站的几个 blog 的统一订阅地址为:

https://feed.fivest.one/

程序基于 DigitalFreelancing 的代码,略作修改,调用了 SimplePie 处理 RSS 的项目库,为每个原始的 RSS 地址生成缓存,避免了频繁读取。我修改后的版本,可以从【这里】下载。

使用说明

  • 配置支持 PHP 的网络服务器,过程略;
  • 下载源文件后,解压到新的 RSS 地址相应的文件夹里;
  • 编辑 index.php,修改如下部分:
$feedlink = "https://feed.fivest.one/"; // 这个新的 RSS 的网址
$feedtitle = "fivestone"; // RSS 名称
$feedhome = "https://fivest.one"; // 你的网站地址(在 RSS 阅读器里点击 Title 可以进入)
$feeddesc = "fivestone's posts aggregation"; // RSS 描述

$feeds = array( // 需要合并的 RSS 网址列表,以引号和逗号分隔
    'https://a.fivest.one/feed',
    'https://b.fivest.one/feed'
);

$time_zone = 'Asia/Taipei'; // RSS 使用的时区
$item_number_limit = 20; // 新的 RSS 显示的文章数上限
$creativeCommons_license = 'https://creativecommons.org/licenses/by-sa/4.0'; // 你选择的知识产权协议(可以自行修改或为空)
  • 根据你的网络服务器的权限配置方式,可能需要把 cache 文件夹设为群组或全部可写
chmod g+w cache 或者 chmod a+w cache
  • 也可以把 index.php 改名,或者复制到其它位置,分别配置,生成多个这样的聚合 RSS。注意要调整文件中的相对路径:
include_once('./simplepie/autoloader.php');

曾经,以及现在,都拖了很多篇 blog 没有写。很多时候,起初只是一个想法,在脑子里萦绕,渐渐地有了大纲,连文章结构甚至一些辞句都有了。最后还是没有写出来。日子久了,也就渐渐忘了要写那篇东西时的思路和目的。

可以为拖延症找到很多理由:blog 式微了,在这里写了也没人来看;又或者有些东西写了反而怕被人看到;以及沮丧的时候,也不知道写出来,面对这个世界,能有什么作用。——但这些可能都不是多么重要的理由。本来我的 twitter 和 blog,就是在有些刻意地无视那些和其它网友交互的社交功能,而只是旁若无人地顾自说话。

但文章写出来,并不只是自己在某个时候,某种状态的展现;写作的过程,也是形成那些状态的过程。一些在脑子里萦绕的、模糊的、犹疑的,通过文字被固定下来。好像彷徨中为自己确立一个方向。

而我有些害怕这些方向。又或许在某些时刻,觉得自己最好还是不要,让某些状态清晰起来。

WordPress 使用 SQLite 数据库

之前写了一半的,如何在轻量级个人 VPS 上搭建各种服务的帖子。一时懒得去把坑填完了。但前几天突然发现自己落入了思维误区:为了配合 Mastodon 或 Pleroma,总想着如何把 WordPress 从 MySQL 迁移到 PostgreSQL。——但是,其实完全可以用 SQLite 啊!对于偶尔才更新一篇的个人 blog 用户,把数据库放在一个 SQLite 文件里,不需要另外安装数据库服务,完全是可行的。

用 Docker 观察内存开销。对于新建的 wordpress 站点,wordpress 本身(包括 php-fpm、nginx)占用内存大约是 40-100M(使用缓存插件后会减少);MySQL 数据库占用内存 200M,随着渐渐使用,有着近千篇文章和评论的 blog 站点,MySQL 占用内存会达到 500M 甚至更多。 ——数据库的这部分内存,使用 SQLite 后,完全是可以省下的。

可以通过 SQLite Integration 插件,安装基于 SQLite 的 WordPress。

WordPress 官网的插件页面,因为作者失联而停更。但隐藏的插件下载链接,一直都还有效:

https://downloads.wordpress.org/plugin/sqlite-integration.1.8.1.zip

UPDATE:上面这个原作者已经停更了的代码,只支持到 php 7.4,在 php 8 里已经失效了。大家可以继续用,但要注意 wordpress 的 php 环境版本。推荐使用 Github 上这个插件的分支,已经被好心人升级到了 php 8.1。

使用非常简单,就是把 db.php 复制到 wp-content 目录里,同时确保你的系统安装了 php-sqlite3 模块。这里有篇攻略。现有的站点,可以通过 Duplicator 之类的 wordpress 备份插件,或者 wordpress 自身的导入导出功能,进行迁移,不需要进行数据库级别的转换操作。

注意事项:

1. 最重要的,数据库的文件的存放位置,这个一定要改!默认的数据库位置是在 wp-content/database/.ht.sqlite,是会被人通过浏览器从 http://website/wp-content/database/.ht.sqlite 直接下载的!虽然插件在 database 文件里添加了 .htaccess 权限控制,但对于如今大家用的 Nginx,是默认无效的。

在 wp-config.php 里添加设置:

define('DB_DIR', '/absolute/custom/path/to/directory/for/sqlite/database/file/');
define('DB_FILE', 'custom_filename_for_sqlite_database');

可以更改数据库文件的存放位置。强烈建议把数据库文件,放到无法直接用网址从外部访问的目录(记得给那个文件夹授权可写)。

2. SQLite 不适合多线程的高并发使用。如果网站会有多个用户同时在后台编辑,那么网站不适合使用 SQLlite;如果只有一个写作者自己编辑 blog,就很合适。但要避免使用那些,在一般访客浏览网站时,也会导致对数据库进行写入的插件,如:

  • WP Statistics 这样的访客统计插件,会把来访者的每一次点击,都记录到本机数据库里。建议使用 Google Analysis 之类的外置统计软件(Google 给 wordpress 做了个官方插件 Site Kit by Google),通过在页面嵌入 js ,发送访客数据到 Google 服务器,不会写入本地数据库。
  • 官方的防垃圾评论插件 Akismet Anti-Spam,其实也是先把每条评论写入本地数据库,再判断是否垃圾的。如果被机器人大量发送垃圾评论,也会造成数据库写入的压力。建议使用 WP Captcha 之类的验证码插件(可以单独使用或配合 Akismet 一起用),把大多数垃圾评论在写入数据库之前就过滤掉。

3. 使用 WP Super Cache 插件,为网站生成缓存文件,可以极大地减少对数据库的读取操作。个人用户完全可以在插件设置里,关闭默认的 Garbage Collection 功能。


网上搜到的 WordPress + SQLite 的 docker images(12),Wordpress 和 php 的版本都有些过时了,本身也有一些小问题(如数据库文件夹的权限设置),建议修改 Dockerfile 然后自行编译。回头有时间我去改个试试。

WordPress 的 ActivityPub 插件

试用一下 WordPress 的 ActivityPub 插件(官网 / Github)。

主要功能,就是在 wordpress 上,建一个 Fediverse 账号,Mastodon / Pleroma / Misskey / Honk……的用户可以 follow 这个账号。新的 blog 文章发布时,这个账号会发一条嘟文,大家可以转发这条嘟文。followers 对这条嘟文的回复,会自动同步到 blog 文章的评论区。

就像我为这个 blog 建的 fedi 账号:@[email protected]

需要指出的是,并不存在 blog.fivest.one 这样一个 fediverse 实例。陌生人搜索这个账号,看不到任何历史嘟文;这个账号不能去 follow 别人,不能对别人说话,不能回复别人对自己嘟文的回复,也不能看到多少人转发点赞了自己的嘟文。——这些功能也许以后会有,但目前,这个插件所做的,只是在新 blog 发布的那一刻,向所有 follow 这个 id 的账号,push 一条嘟文。这条嘟文,在 blog 服务器上,并没有保存;而只存在于 follow 它的那些实例上,再被人转发到更多实例。

当 blog 的文章被删除时,这个插件也会通知所有的 followers,从他们的实例上删除对应的嘟文。但是就像我说过的,这个机制并不能把那些,被转发到其它实例的嘟文,也一起删除。所以,当你在 blog 按下发布按钮的一刹那,带着你所写的全部内容(或者摘要,可设置)的嘟文,就可能会永远飘在 fediverse 世界里,无从反悔。所以,写完这篇文章后,我还不确定自己是否会继续用这个插件……

所以我只是觉得这个插件运行的机制很有趣,向大家介绍一下而已。它仅仅是通过 ActivityPub 协议,和其它实例通信,而本身并没有创建实例。这个插件在 wordpress 的数据库里,甚至没有新增一个 table,而只是把 followers 的公钥,存到了 wp-options 里(我觉得这么折腾 options 表,有点过犹不及了……)。总而言之,这是个超级轻量化,在 wordpress 基础上,完全不产生多余开销的东西。

我之前吐槽过,目前所有的 Fediverse 引擎,都是用软件工程模块,匆匆拼出来的臃肿怪兽:开销巨大,数据结构不美观,依赖的技术模块未必有长久的生命力,安全性抗冲击性都很差……其实我很期待,一个单用户版的,完全没有 local 功能,支持 ActivityPub 协议的引擎。结构的简洁程度,和资源的开销,要比现在这些要好很多。从这个插件可见一斑(虽然这个插件和完整的个人版 fedi 实例,是完全两回事……


测试了一下。好像只有 follower 的回复(公开 or 私密)才会同步到 blog 的评论区;陌生人的不可以。但目前还没有做 follow 的审核通过机制。所以理论上是可以用这个功能发垃圾评论……

以及目前还没有让用户修改个人简介的功能,图片上那些简介,都是我在插件 templates/author-json.php 里手动改代码的。

社交平台的六围

对各种用户提供内容的平台进行评价和比较时,我觉得大家争吵的,往往是不同维度的东西,而每个人更在意的方向并不相同。我列了一下,大概有这些因素。首先要做的,是自己打个权重,看看你对每个因素是不是真的在意(譬如公众传播度在有些人心中的比重,是远大于帖子是否会被删的——这未必是坏事)。然后就可以像游戏里角色的六围那样(其实列出来的不止六项),给每个平台逐项打分。

  • 思维自由度:你在写东西的时候,多大程度上,会受到其它因素的约束和干扰?这不仅仅指在真理部面前进行自我审查,也包括你所在的社区的发言氛围,以及你是否介意朋友们看到你发言时的反应。
  • 信息存活性:你的发言会不会被删,以及在更大范围上,你所在的平台会不会突然就没了……(或许这两条应该分开算?
  • 信息持续性:一方面是指热度:文章会不会过两天就沉下去,再没人关注(其实所有平台都会这样)。另一方面,哪怕没人关注,你是否希望文章一直存在,被需要的人偶尔搜出来看看?还有一点就是,当你换了平台,或者换了图床的时候,能不能用某种技术手段,让你的外链一直有效?
  • 便于讨论:你的文章是否便于让同好们进行讨论?以及,你所在的平台是否能聚集你的同好?
  • 公众影响:为了赚钱或者社会责任感,你是否宁愿自我阉割,也希望文章尽可能地被更多人看到?
  • 跨平台开放性:文章是否能让平台之外的用户看到?
  • 隐私安全:如果作者没有主动泄露个人信息,平台的架构以及管理人员,能否防止你被喝茶或者被人肉?
  • 技术便利性:建站、管理、日常访问、翻墙……是否方便?(其实我应该把管理员和普通用户分开的)

此外当然还有更多的参考因素(界面美观、用户体验、是否免费……),这里只是提供这样一个比较的思路。

我这里随手列了几个例子。一些网站我不常用没什么发言权:Facebook、Lofter、Matters、AO3、豆瓣……大家可以自行吐槽。

以下是吐槽部分:

  • 虽然 Mastodon 最初是作为避免 twitter 越发严重的政治审查而存在的,但目前各个实例中的用户趋向(或者说他们希望能趋向)同质化,导致目前给我的感觉,在 Mastodon 里说话的自由还不如 twitter。
  • 在 Google Reader 的时代,以及 Disqus 等平台试图统一 blog 评论体系的时代,blog 的讨论性是接近四颗星的,但目前只能用凄惨来形容。虽然每篇文章还是有评论区,但大家宁愿在 twitter 的链接下面回复,而没有人去文章下面留言了。
  • Facebook 这种完全建立在实名上的讨论群体,以及随之关联的发言规范,和我完全就是不同的世界,索性不予评价。

Hello Matters.

在 matters.news 上面开了个账号,可能会同步一些文章过去。这里是开篇介绍以及一些关于 blog 的吐槽。还不知能不能在那边写下去。


一直在考虑,要不要在 matters 开个账号,把自己 blog 上的一些文章同步过来。在 matters 关注了一段时间,这里确实集中了一部分很优秀的社科类写作者,希望能够继续关注下去。而且这年头坚持写中文 blog 的人确实不多了,也很希望能够有一个这方面的社群,能够进一步交流。

但还是有一些顾虑。


首先,作为原教旨 blog 拥护者,我一直认为 blog 作为一个开放系统,需要满足两个条件:

  1. 系统自带原生 RSS 订阅;
  2. 作者可以选择向所有人(无论是否 matters 用户)开发评论功能。

这两个条件,matters 一条也不符合。虽然有第三方工具实现 RSS,但毕竟不是 matters 自带的功能。而评论功能只有注册了一段时间的站内用户才可以用。所以我其实是不喜欢 Matters Medium 这类的网站形式的。当然关于这些指摘,有着各种解释:譬如这样更有利于付费订阅、避免垃圾评论和网络水军、以及未必只有开发系统才叫做 blog……但我还是认为这些都不是必须通过这种半封闭的架构,才能解决的。这些其实都是对互联网开放性的越来越深的伤害。——总之你们可以把这当作 blog 老用户的吐槽。

ps,在 matters 通过第三方生成 RSS 地址的攻略:
https://rsshub.app/matters/author/fivestone
把链接最后面的 id 换成你想要关注的作者 id。


其次,经过互联网十几年的风风雨雨,我现在对任何 blog 平台,乃至任何网站,几年后会不会倒闭,完全没有信心。这不是在诅咒 matters 啦,只是想到自己投入心血维持的社交网络,几年后因爲各种莫名的理由消失,就没心思把它继续下去。区块链保存也好、众筹维护也罢,其实都只是噱头。即使不涉及政治审查,仅仅是由于资本运作而倒闭的网站,无论墙内墙外,数不胜数:微软space、Google Reader……如今靠谱的老牌 blog 平台,似乎只剩下 wordpress 和 blogspot,免费版的页面上被塞满了难看广告。似乎只有自建域名和服务器,才是长久保存的王道。但那些自建 wordpress 以及用 Github 静态空间的 blog,需要的技术门槛也确实很高,能做到这一点的人,写出来的 blog 内容,也基本是纯IT(笑)。在 blog 式微的时代,维持一个低门槛的长期写作环境,确实是很难的事情。


在这里写东西,似乎要比自己写 blog,要更吃力一些。或许是因爲这套 LikeCoin 的打赏体系,吸引了很多希望从写文章而获得收入的人,所以写出来的文章更像是精心雕琢后可以直接发到正刊上的稿件。这当然没什么不好,但对于我这种习惯于写碎片,一个题目可能分成三四篇,想到什么就随便写一段发出去的人,还是会有些压力。但随著 matters 的用户群的增加,我也看到有人来这里写碎片化的日记了。

关于 LikeCoin 这套体系我还不是太明白。我在自己的 wordpress 上也安装了 LikeCoin 的点赞插件,但似乎只是把 likes 的账目记在 matters 名下,在用户交流的方面,和 matters 系统不是互通的。总之大家赶紧给我凑 15 个赞,让我好去评论别人。^^


最后,是关于简体字的问题。我更倾向于把简体字正体字的分隔归为历史因素,而不赞同通过政治或者「正体字更有文化」之类的理由,把两者明显割裂开来。Matters 无疑是正体字的大本营。虽然我两种字体读写都没有障碍,但我自己的 blog 确实是简体。一方面我认为其实没有必要在这里发文时必须用正体字,从而去迎合什么;但另一方面,我也确实担心简体字在这里会受到一定程度的歧视,并对这种状况觉得有些悲哀。


就这样吧,每次开篇都要很正式的样子写一堆(笑),也不知道会在这里坚持多久。

我为什么来推特

突然大家在回忆这个,于是也整理一下。

其实是先有 blog 再有 twitter 的。

2007年,在某个国内 blog 网站(好像是已经倒闭的 blogcn),看到个功能:在首页更新自己的一句话状态,类似于 QQ 签名档的样子。于是也想在自己的 wordpress 上面搞一个。研究了一圈,发现与其在 wordpress 上写代码,不如去注册 twitter,然后把最新的 twitter 信息同步过来。

当时有个叫做 twitter tools 的 wordpress 插件,可以定时把自己最新的推,存储到 wordpress 的数据库里,然后就可以本地调用,用纯文本的格式显示在首页上。——比 twitter 官方,以及各家山寨们,用 JavaScript 或者嵌入 frame 的方式显示,要清爽很多。这可能也是当时为什么没有首先用饭否、叽歪,等山寨货的原因。

后来还自己写了个插件,把存下来的推,每个月合成一篇 blog 文章。再后来 twitter API 改版,twitter tools 的插件也就不能用了。而 JavaScript 或者 frame 的方式,墙内的访问者是看不到的,反而会影响网页加载,也就没法用。(同样的道理 Google Analytics 也不好用)。一直想自己再写一个,基于新的 API 或者 RSS 把推同步到本地的插件的,但始终没有弄。

所以对我而言,注册 twitter 最初仍然只是自说自话的另一种方式,和 social 完全没关系。

没有Google Reader了,blog还要继续。

RT @ztpala: 没有Google Reader了,blog还要继续。

ps,但首先要搞定在blog上备份twitter的问题。twitter-tools倒是推出了配合Social插件,支持API 1.1的新版twitter认证,装上之后能从wordpress发推,但实时备份目前还没反应。而且原来是用新的数据表保存tweets,现在居然都存到wp-posts里了,导入旧推后,文章序列号从900多直接跳到5000多……挠头ing