summaryrefslogtreecommitdiff
path: root/content/article
diff options
context:
space:
mode:
authoreltrac <hi@eltr.ac>2026-03-10 22:00:25 +0800
committereltrac <hi@eltr.ac>2026-03-10 22:00:25 +0800
commit9b16ecf2b1e12b19eab843832e2d6393158b83f4 (patch)
treee91574c9db344d7b01c86c39e9f898e7ff3e6b80 /content/article
parent8edc9c8882f09eb955e33279b7fb9f5fe70f417e (diff)
docs: update draft
Diffstat (limited to 'content/article')
-rw-r--r--content/article/webmention.md235
1 files changed, 233 insertions, 2 deletions
diff --git a/content/article/webmention.md b/content/article/webmention.md
index ff822909..4dd39476 100644
--- a/content/article/webmention.md
+++ b/content/article/webmention.md
@@ -99,7 +99,7 @@ POST https://webmention.app/check/?url=https://my.site/post-xxx
### 使用 webmention.io
-最简单也是最常用的第三方 Webmention 接收服务是 [webmention.io](https://webmention.io/),我也在使用。这个服务是开源的,所以还算值得信赖。要使用他们的服务,你首先需要配置 [IndieAuth](https://indieauth.com/),也就是表明你是这个网站的主人,怎么做到呢?
+最简单也是最常用的第三方 Webmention 接收服务是 [webmention.io](https://webmention.io/),我也在使用。这个服务是免费且开源的,所以还算值得信赖。要使用他们的服务,你首先需要配置 [IndieAuth](https://indieauth.com/),也就是表明你是这个网站的主人,怎么做到呢?
在网站的 `<head>` 添加:
@@ -111,7 +111,7 @@ POST https://webmention.app/check/?url=https://my.site/post-xxx
把 `alice` 改成你自己的用户名。这个标记的意思是,这个网站的主人有 GitHub、Twitter 和电子邮箱账号,用户名或地址如上。接下来,确保你的 Twitter 账号页面或 GitHub 账号资料里有链接到这个网站。这样一来,你就证明了自己拥有这些账号,IndieAuth 也就允许你用这些账号登录。你不必配置全部三个账号,只需要一个有效的登录方式。如果是邮箱的话,IndieAuth 就会给你发送一封电子邮件确认登录。
-你还可以把 `<link>` 写成 `<a>` 标签,如果网页里已经有这些账号页面的链接了,只需要给 `<a>` 加上 `rel="me"` 即可。这种标记方式叫作 microformats,是一种开放标准,后文还会提到。
+你还可以把 `<link>` 写成 `<a>` 标签,如果网页里已经有这些账号页面的链接了,只需要给 `<a>` 加上 `rel="me"` 即可。这种标记方式叫作 microformats,后文还会提到。
配置好 IndieAuth 之后,在 [webmention.io](https://webmention.io/) 输入域名登录,接下来会进入仪表盘。现在,你需要在 `<head>` 里面指定 webmention.io 作为接收器,添加这段内容:
@@ -123,9 +123,240 @@ POST https://webmention.app/check/?url=https://my.site/post-xxx
接下来 webmention.io 就能够帮你接收 Webmention 了。这个服务是 [Aaron Parecki](https://aaronparecki.com/) 提供的,如果你觉得不错,可以去支持他!他还是 IndieWebCamp 的创始人和 OAuth 工作组的编辑者。
+好了,现在你能接收 Webmention 了,数据存放在 webmention.io 的服务器里,要怎么查看接收到的 Webmention 呢?有这样几种方式:
+
+1. 在[仪表盘](https://webmention.io/dashboard)查看最近的 Webmention。
+2. 在[设置](https://webmention.io/settings)获取 RSS/Atom 订阅源,使用 RSS 阅读器查看。
+3. 配置 [Webhook](https://webmention.io/settings/webhooks),在有新 Webmention 时向指定 URL 发送 HTTP 请求,可以配合 [Bark](https://github.com/Finb/Bark) 或 [ntfy](https://ntfy.sh/) 推送到你的手机上。
+4. 通过 [API](https://github.com/aaronpk/webmention.io#api) 获取数据。
+
+如果你想通过 API 把 Webmention 展示在自己的网站上,最简单的方法是使用 [webmention.js](https://github.com/PlaidWeb/webmention.js/)。把 JavaScript 文件放在自己的网站上之后,在需要显示 Webmention 的地方添加:
+
+```HTML
+<div id="webmentions"></div>
+<script src="/path/to/webmention.min.js" async></script>
+```
+
+具体的使用方式见项目文档。
+
+如果能力允许,可以自己编写渲染逻辑,毕竟 API 已经有了。
+
+### 自托管 Webmention 接收端
+
+webmention.io 很好用,配合 webmention.js,甚至不需要自己写一行代码,不需要部署任何服务,就能接收并展示 Webmention,这对大部分人来说已经够了。不过,如果你很在乎自己的数据,并希望尽可能少依赖第三方服务,那么你大概要自己部署接收端了。
+
+在可以自己部署的 Webmention 接收端中,使用者比较多的是 Horst Gutmann 维护的 [webmentiond](https://github.com/zerok/webmentiond/),用 Go 编写,存储基于 SQLite,简单轻量。此外还有用 Rust 编写的 [WesleyAC/webmention-receiver](https://github.com/WesleyAC/webmention-receiver) 和用 Python 编写的 [capjamesg/webmention-receiver](https://github.com/capjamesg/webmention-receiver)。
+
+对于重复造轮子这件事,我们国人也是不输(奇怪的比较)。[Chlorine](https://chlo.is/) 不久前用 Rust 写了一个 Webmention 接收端,名为 [CircleAt](https://codeberg.org/chlorine/circleat),而我也用一门 Lisp 方言开发了 [Weepinbell](https://codeberg.org/eltrac/weepinbell),最近才发布 [v0.1.0](https://codeberg.org/eltrac/weepinbell/releases/tag/v0.1.0) 版本。不过我不建议你用 Weepinbell,因为还没有正式投入使用,可能存在一些问题,进入稳定版本之后我会再发一篇文章的。当然,如果你愿意贡献的话,我将感激不尽。
+
+在开始之前,我得警告读者,Webmention 作为一门小众技术标准,使用者很少,自托管接收器的更少,如果遇到问题,可能很难找到解决方案和能够提供帮助的人(虽然我很欢迎有人来问我啦)。如果对自己的技术没什么信心,webmention.io 已经很好了,比能够自托管的选项都要成熟不少。
+
+不过剩下的我也没什么好讲的了,如果你决定自托管,那就选择一个自己觉得不错的接收端软件部署到服务器上。至于如何查看接收到的 Webmention 和如何展示,不同的接收端都有实现细节上的不同,这里略过。
+
## 让 Webmention 生动起来:microformats
+[microformats](https://microformats.org/) 是一系列开放数据格式,建立在已被广泛采用的标准之上(比如 HTML)。它并不是和 Webmention 强绑定的,实际上 Webmention 标准完全没有提到过 microformats,只不过 IndieWeb 上的人很喜欢把它和 Webmention 一起用。说起来,应该是 webmention.io 的维护者 Aaron Parecki 带的头,webmention.io 默认支持解析 microformats。
+
+由于没有 microformats 也不影响使用 Webmention,如果你不感兴趣的话,可以跳过这一节。
+
+### microformats 是什么?
+
+回答这个问题之前,先要了解它解决了什么问题。
+
+网页可以是任何东西,可以是 Web 应用(比如 Notion 这样的在线笔记),可以是小工具(比如计算器、格式化工具、视频下载器),可以是相册,也可以是一篇文章,可以是日历。同一张网页也可能包含各种各样的东西,一篇博客文章中有页面标题、主体内容、标签、评分、回复等等。
+
+网页的具体结构也是不确定的,为了实现不同的排版和效果,不同网站的 HTML 结构完全不同。有的可能是这样的:
+
+```HTML
+<main id="container">
+ <h1 id="post-title">Title</h1>
+ <article id="post-content">
+ <p>Content</p>
+ <!-- ... -->
+ <p>Author is ..., follow me on <a href="https://mastodon.social/@author">Mastodon</a></p>
+ </article>
+ <div id="comment">
+ <!-- ... -->
+ </div>
+</main>
+```
+
+也有可能是这样的:
+
+```HTML
+<main id="container" class="flex justify-center items-center my-10 mx-auto p-4">
+ <header class="max-h-lg shadow-lg">
+ <div class="rd overflow-hidden">
+ <img src="/posts/xxx/banner.jpg" class="block">
+ </div>
+ <h1 class="font-extrabold text-3xl">Title</h1>
+ <p class="font-semibold text-xl">Subtitle</p>
+ </header>
+ <article class="text-md leading-loose prose">
+ <div id="post-content">
+ <!-- ... -->
+ </div>
+ <div id="post-endnotes">
+ <ul>
+ <!-- ... -->
+ </ul>
+ </div>
+ <div id="author-info" class="bg-white px-4 py-6 my-2 shadow">
+ <p>Author Name</p>
+ <p>Description</p>
+ <a href="https://mastodon.social/@author">Mastodon</a>
+ </div>
+ </article>
+ <footer>
+ <!-- ... -->
+ </footer>
+</main>
+```
+
+偶尔还能见到一些莫名其妙的 HTML 结构,比如我就见过这样的:
+
+```HTML
+<div id="scroll-body">
+ <div id="contant-wrap-wrap">
+ <div id="content-wrap">
+ <div id="main-content">
+ <div id="page-content"></div>
+ </div>
+ </div>
+ </div>
+</div>
+```
+
+~~简直有大病。~~ 无论如何,尽管它们的结构不同,但包含的内容是相似的,换句话说,**数据结构**是相似的。他们都有可能是一篇文章,包含页面标题、内容、作者信息等等,这篇内容同时还有可能是另一篇内容的回应、点赞或转发。
+
+被浏览器渲染为图形过后,人读起来会理所应当地觉得这些就是相同的数据,但在机器看来就难了。HTML 结构有无限种可能,要怎么让机器快速且准确地判断某个网页属于什么类型的内容,它包含了哪些结构化的数据?
+
+其实已经有一些方案被提出了,比如被广泛使用的 [Open Graph 协议](https://ogp.me/)。网页只要按照标准,添加一些 `<meta>` 标签,就可以使其成为一个数据对象。Facebook 等社交媒体,在遇到这些链接的时候,会爬取 Open Graph 的内容,生成更具视觉效果的卡片。
+
+以下是 Open Graph 的一个例子:
+
+```HTML
+<meta property="og:title" content="The Rock" />
+<meta property="og:type" content="video.movie" />
+<meta property="og:url" content="https://www.imdb.com/title/tt0117500/" />
+<meta property="og:image" content="https://ia.media-imdb.com/images/rock.jpg" />
+```
+
+microformats 是类似的东西,但他没有规定新的 `<meta>` 标签类型,也不像另一个标准 [JSON-LD](https://www.w3.org/TR/json-ld11/) 一样要求插入一大段包含 JSON 的 `<script>` 标签。它就建立在最基础的 HTML 之上。
+
+以下是用 microformats 标记的一篇博客文章示例。
+
+```HTML
+<article class="h-entry">
+ <h1 class="p-name">Microformats are amazing</h1>
+ <p>Published by <a class="p-author h-card" href="http://example.com">W. Developer</a>
+ on <time class="dt-published" datetime="2013-06-13 12:00:00">13<sup>th</sup> June 2013</time></p>
+
+ <p class="p-summary">In which I extoll the virtues of using microformats.</p>
+
+ <div class="e-content">
+ <p>Blah blah blah</p>
+ </div>
+</article>
+```
+
+注意到 `class` 的值了吗?`p-name` 标记了这篇博客文章的名字,`p-author` 标记了作者,`p-summary` 标记了这篇文章的总结摘要,`e-content` 则是这篇文章的内容。最外层的 `h-entry`,标记这是一个条目,博客文章、社交媒体发帖和维基页面等等,都可以用这个类名标记。
+
+要实现 microformats 标准,你不需要在其他地方添加任何别的格式的数据,只需要在原有的 HTML 上操作就好了。刚刚我们看到的是 [h-entry](https://microformats.org/wiki/h-entry) 格式,用来标记发布在万维网上的内容,除此之外,还有用来标记人和组织的 [h-card](https://microformats.org/wiki/h-card),用来标记日历和事件的 [h-event](https://microformats.org/wiki/h-event) 等等。
+
+我们刚才用来配置 IndieAuth 的 `<link rel="me">` 标签,也是一个 [microformats 格式](https://microformats.org/wiki/rel-me)。它更常见的用法是直接标记在 `<a>` 标签上:
+
+```HTML
+<a href="https://github.com/tantek" rel="me">@t</a>
+<a href="https://tantek.com/" rel="me">https://tantek.com/</a>
+```
+
+`rel="me"` 本身不是用来配置 IndieAuth 的,只是标记网站站长的其他网页链接的一种方式。IndieAuth 只是使用了 microformats 的这个格式而已。
+
+总而言之,`microformats` 是名副其实的「微格式」,不需要对网站结构做出太大改动,就可以标记结构化的数据。
+
+### 和 Webmention 的关系
+
+我猜测除了 [webmention.io](https://webmention.io/) 之外,没有太多接收端实现了解析 microformats 的能力(不过,[Weepinbell](https://codeberg.org/eltrac/weepinbell) 可以!)。最初 Webmention 仅仅是「A 网页提及了 B 网页」的通知,并没有什么复杂的分类,但 microformats 的使用让一切都不简单了起来。
+
+一般来说,相互提及的网页都是博客文章,文章是用 microformats 的 `h-entry` 标记的。这个格式除了标记基本的元信息之外,还有这样的属性:
+
+- `u-in-reply-to`:这个 `h-entry` 回复了哪篇文章
+- `p-rsvp`:这个 `h-entry` 是对什么的 RSVP,即表明自己是否要参与某次聚会、活动或事件
+- `u-like-of`:这个 `h-entry` 是对哪篇文章的喜欢(点赞)
+- `u-repost-of`:这个 `h-entry` 是对哪篇文章的转发
+
+比如,Bob 回应了 Alice 的文章,它在文档开头提及了 Alice 的文章,它可能是这样写的:
+
+```HTML
+<div class="h-entry">
+ <h1 class="p-name">对 Alice 文章的回复</h1>
+ <div class="e-content">
+ <p>前几天我在 Alice 的博客上读到了
+ <a class="u-in-reply-to" href="https://alice.blog/">
+ 一篇有趣的文章
+ </a>,
+ 我很受启发。</p>
+ <p>对这个问题,我也有相似的思考。</p>
+ <!-- ... -->
+ </div>
+</div>
+```
+
+你注意到了吗?Bob 把文章中提及的链接标记为 `u-in-reply-to`。如此一来,这篇文章在能够解析 microformats 的程序看来,就是对 Alice 文章的一篇回应。如果是 `u-like-of`,就是对那篇文章的点赞,`u-repost-of` 就是转发。
+
+至于 `p-rsvp`,我觉得这个设计有点大病——真的会有人写网页公开发 RSVP 吗?这种东西难道不应该私下交流吗?无论如何,它是存在的,你可以用 microformats 标记 RSVP,也意味着你可以用 Webmention 来发 RSVP 通知他人你是否决定出席某次活动。
+
+具体而言,Webmention 和 microformats 这两个标准是这样一起使用的:支持解析 microformats 的 Webmention 接收端,在收到请求时,除了做最基本的检查之外,还会解析 `source` 网页中的 microformats,如果有的话,就一起保存下来。
+
+IndieWeb 上的居民会根据 `h-entry` 是否包含 `u-in-reply-to` 等属性,决定展示 Webmention 的方式。如果有 `u-in-reply-to`,就显示为回复或评论;如果有 `u-like-of`,就显示为点赞;如果有 `u-repost-of`,就显示为转发。以下是 Barnaby Walters 的网站实现这一展示方式的例子。
+
+![](https://r2.eltr.ac/geedeapro/article/webmention/800px-waterpigs-webmention-display.png "Barnaby 的[网站](http://waterpigs.co.uk/)")
+
+如果都没有,那就当作普通的提及,也就是最原始的 Webmention。
+
+### 在 Webmention 中显示自己的名字和头像
+
+上一小节解释了 `h-entry` 格式,用来标记内容。用来标记作者时,可以用到 `h-card` 格式。
+
+```HTML
+<a class="h-card" href="https://tantek.com/">Tantek Çelik</a>,
+
+<span class="h-card">
+ <a class="p-name p-org u-url" href="https://microformats.org/">microformats.org</a>
+</span>
+```
+
+`h-card` 本来是独立的,用来标记人和组织的格式,但它也可以作为 `h-entry` 的子属性 `p-author`,放在 `h-entry` 里,标记这个内容的作者。
+
+```HTML
+<div class="h-entry">
+ <div class="p-author h-card">
+ <img src="https://aaronpk.com/images/aaronpk.jpg" class="u-photo" width="40">
+ <a href="https://aaronpk.com/" class="u-url p-name">Aaron Parecki</a>
+ </div>
+</div>
+```
+
+这样,其他软件在解析 microformats 的时候,就能发现你的名字和头像了。一般来说也会展示在 Webmention 里。
+
## 同步来自联邦宇宙的提及
+你可能怀疑会不会真的有人这样用 microformats,给链接标记 `u-in-reply-to` 这样的类名总归有点麻烦,大部分时候我们只是简单提及一篇文章而已,不见得就是对那篇文章的直接回应,或者说点赞和转发。这些东西更像是社交媒体上会用到的。
+
+嗯?社交媒体?
+
+既然我们在讨论开放的标准,那就不得不提及开放且去中心化的社交媒体了。是的,我说的就是[联邦宇宙](https://jointhefediverse.net/?lang=zh-hans)。有没有办法把来自联邦宇宙的点赞、回复和转发,以 Webmention 的方式同步到网站上呢?
+
+答案是使用 [Brid.gy](https://brid.gy/),这个服务允许你用 Mastodon 账号(以及其他兼容 Mastodon API 的联邦宇宙软件)登录,并将社交媒体账号与你的网站桥接起来。它做的事情很简单:
+
+1. 每隔一段时间扫描你的社交媒体时间线,以及其他人与你的互动。
+2. 如果发现你的某篇帖文包含你的网站上的 URL,而又有人点赞、回复或转发了这篇帖文,那么就视作这个人点赞、回复或转发了你网站上对应的这篇文章。
+3. 创建一个占位 HTML 页面,包含用 microformats 标记的 `h-entry`,以这个占位页面作为 `source`,给你网站上的页面发送 Webmention。(如果你直接访问这个占位页面,会被跳转到实际的联邦宇宙帖子,但 Webmention 接收器会把这个占位页面视作真实的 `source` 地址)
+
+如此一来,你的网站就通过 Webmention 和联邦宇宙互通了。
+
+我的网站就是这样做的,拉到页面最下方,你就能看到来自联邦宇宙的点赞和回应,不过我还没想好应该如何展示「转发」这个类型的 Webmention。
+
## 自己动手写 Webmention 接收端