Skip to content

技术

两个月,一群 AI,和一个从零手搓的 App Store

11 min readUpdated Sep 18, 2026902 views

This post has not been translated into English yet. You are reading the original.

In this room
  1. 一、缘起:我为什么要自己造一个
  2. 二、我们是怎么干活的
  3. 三、这两年……不,这两个月,我们到底做了什么
  4. 3.1 那套会呼吸的视觉
  5. 3.2 点一下就展开的文章
  6. 3.3 一个真的能听的音乐播放器
  7. 3.4 YouTube 式的视频文章
  8. 3.5 一个 Cloudflare 级的访客大屏
  9. 3.6 一整套安全系统:GateKit
  10. 3.7 一个平台级的、有密码学签名的更新系统
  11. 3.8 设置永不丢失
  12. 3.9 还有那些数不清的小东西
  13. 四、那些藏在版本号里的故事
  14. 五、致谢

你现在看到的这个博客——顶上那块会随天气变化的呼吸感封面、点一下就像 App Store 里应用卡片那样丝滑展开的文章、底部那条悬浮着的液态玻璃导航坞——它没有用任何现成的主题,没有引一行前端框架,没有热链一张图片。

它是从一片空白的文件夹开始,用两个月时间,一个版本一个版本,亲手搓出来的。

到今天,它走到了 3.69。

我想认认真真地,把它介绍给你。


一、缘起:我为什么要自己造一个

在此之前,这个站(iws.tw)跑的是 Hugo,用的是我自己写的开源主题 LoveClaude 一个 Claude/Anthropic 气质的静态博客皮肤。它挺好,但静态博客有静态博客的天花板:我想要评论、想要访客分析、想要绝对的安全、想要一个能在后台点点点就配好一切的控制台、想要访问控制和邀请制、想要一个能真正"活"起来的站。

更重要的是,我心里有一个很具体的画面:我想要一个像 iOS 26 App Store 那样的博客。

不是"看起来像",是骨子里像。App Store 的 Today 页、Arcade 页那种大图叙事;和那种会讲故事的卡片;应用图标那种圆角矩形(squircle)的精致;iOS 26 那层"液态玻璃"的通透质感。文章不该是一行行灰扑扑的链接,它该是一张会呼吸的卡片,你点它,它像应用启动那样从封面处展开成全屏。

带着这个画面,我做了一个当时看起来有点疯的决定:换到 Typecho,然后从零开始,自己造这套主题。

而"自己",从第一天起,就意味着"我和 AI 一起"。


二、我们是怎么干活的

先说清楚这套协作方式,因为它本身就是这个项目最有意思的部分之一。

我是这个项目的作者和导演。我脑子里有画面、有审美、有那条不能退的底线。

我旁边坐着一位总指挥兼设计师——那是 chat 端的 Claude(Opus 4.8)。它不直接写项目代码。它干的活是:把我脑子里模糊的画面,翻译成一份份"保姆级"的施工规格——每一节都先讲清楚为什么这么做,再给出可以照抄的代码、坐标、参数,而且每一步都能单独验证。它还负责去 GitHub 上把真实的开源实现拆开研究,而不是丢一句"学 Apple"就让人自己悟。它是那个把"我想要的感觉"变成"能落地的工程"的人。

真正在编辑器里敲代码的,是执行端。这个位置换过三次人:

  • Claude Sonnet 5,陪我们走完了最艰难的从 0 到 1(P3.6 到 P3.38),把视觉体系、动画引擎、安全插件的地基全部夯了下来。
  • Kimi K3 接手了中段最庞大的一批(P3.39 到 P3.68),平台级的更新系统、访客大屏的产品级重构、四套封面系统,几乎都在它手里成型。
  • Grok 4.6 是现在的执行端(P3.69 起),接手了最近的字色自适应和收尾打磨。

一份规格,一次实现,一次真机验收。做完一份 build log,截一张图给我看。这个循环,我们重复了两个月,六十九个大版本。

有几条红线,从第一天贯穿到最后一天,一次都没破过:

  • 可移植:所有代码只能写在主题目录和三个配套插件里,只能靠官方钩子,绝不允许改动 Typecho 的核心文件。验收标准很粗暴——把这几个文件夹拷到一个全新的、干净的 Typecho 上,装好,它必须立刻完整工作。这一条,我们兑现了四十多轮。它让这个东西从"一个 Docker 项目"变成了"一个能装、能用、能升级的产品"。
  • 纯原生:CSS、JS、PHP,不引任何前端框架,不上任何构建工具,不依赖任何在线 CDN。所有素材本地化,绝不热链。
  • 实测 > 直觉:任何关于因果、性能、安全的判断,先测再下结论。没复现的问题就说没复现,绝不假装修好了。
  • 能加开关就加开关。

这几条听起来像枷锁,但正是它们,让这个主题干净、独立、可以坦然地拿去开源。


三、这两年……不,这两个月,我们到底做了什么

我尽量完整地讲。这是一个"高大全、DIY 控制力极强"的主题加一整套配套插件,功能是真的多。

3.1 那套会呼吸的视觉

一切从视觉体系开始。首页顶部是一块 HERO 幻灯片——灵感直接来自 App Store 的 Arcade 大图。它不是一张静图,它是一个九宫格式的舞台:每张幻灯片是一篇文章,有大大的封面、会轮播的标题。

最新的一批打磨,恰好就发生在我写这篇文章之前。手机上,浅色封面配深色标题会发糊看不清;而我们的封面五颜六色——紫的、粉的、彩的。于是我们做了一套标题字色自适应:主题会去抓取每张封面的实际主色,然后为标题挑一个收敛的对比色——不是刺眼的正补色,而是旋转 157° 的近补色,饱和度压到中低,明度再根据封面的明暗自动加深或提亮,最后还要通过一道 4.5:1 的对比度校验才算数。封面是紫的,标题就落在柔和的金橙调上;是粉的,就落在暗青绿上。既撞色好看,又绝不糊。

配套的还有一个磨了很多次的小细节:HERO 里的 emoji 该放哪。钉死在正中,两行标题就会撞上来;顶太高又难看。最后定在"居中略偏上"——一个在各种手机比例下都稳的位置。这种像素级的来回,我们走过不止一遍。

3.2 点一下就展开的文章

这是我最得意的交互之一。文章卡片你点下去,它不会跳到一个新页面。它像 App Store 里的应用卡那样,从封面的位置原地展开成全屏的阅读视图,关闭时再缩回原来那张卡。展开动画用的是可中断的 WAAPI,还带 FLIP 形变和拖拽跟手——你甚至能拽着它半路反悔。

文章的封面本身,是一整套学问。我们做了四套封面系统,可以自由混用:

  1. Emoji 封面:一整套 Fluent 3D emoji(3390 个文件,按 Unicode 码点命名),配上一套自研的单色相渐变配方,让封面根据 emoji 的主导色相生成和谐又有质感的背景,还有贴纸化的白边和接触阴影。这套配方本身就调了好几轮才不"发脏"。
  2. CoverKit 模板封面:一个独立插件,复刻了精致的杂志/终端风格模板,用 CSS 容器查询做到任意尺寸自适配,后台还能可视化编辑。
  3. Lucide 静态图标封面:58 枚本地化的线性图标,配可视化选择器和分类色描边。
  4. 动态图标封面:12 枚手绘的 stroke SVG,纯 CSS 关键帧动画。静止时是动画的最终帧,鼠标悬停时播放一次——灵感来自 App Store 应用图标那种"活"的设计语言。

再加上一个统一的封面选择器:横向分类切换、圆盘取色器(手动选背景色相),没选就系统按文章 ID 确定性地随机一个。

3.3 一个真的能听的音乐播放器

博客里嵌了一个响应式的音乐播放器,三种形态:桌面是 Apple Music 那样的窗口,平板是圆圈弹窗,手机是灵动岛式的 CoverFlow。播放状态用 localStorage 持久化,全站统一走一个全局对象,翻页也不断。

配套还有一个 iTunes / Apple Music 式的音乐页,大标题、密集网格、开场的音符弹窗,还有一句"停下来感受音乐和生活"。更狠的是接了 yt-dlp,可以从全网站任何 URL 下载音频并抓取歌词。

3.4 YouTube 式的视频文章

视频文章不套普通文章的皮,它有自己独立的布局:桌面是 16:9 的大视频加右侧播放列表和"其他文章"栏,大量留白,操作条上访客能点赞。整棵 DOM 走 AJAX 无缝换装。

3.5 一个 Cloudflare 级的访客大屏

这是工程量最大的一块,做了产品级的重构。它建立在 Event → Session → Visitor 三层个体画像模型上:每个访客有匿名 token,能看到 TA 的设备、IP、内容偏好、完整的行为时间线。地图是本地化的 Leaflet,有国土热力层和城市气泡;三个时区并排显示;还有一套判断访客真实性的分类器。

最近一次交互重构把它做得特别顺手:点任何一个筛选项(某个系统、某个地区),直接就进到对应的访客列表,而不用自己在控制台里往下滚。深浅色都支持,地图固定比例,离线还能出报告。隐私上有总开关、有保留期、有概率清理——不做跨站强指纹,这是底线。

3.6 一整套安全系统:GateKit

访问控制全部收在一个叫 GateKit 的插件里。它能给文章上锁,支持五种验证方式(密码、邀请码、邮件、真正的 RFC6238 TOTP、Telegram Bot),后台可配。失败拦截、内容旁路保护(受保护的正文在服务端就被剥掉,前端拿不到)、真正的密码学校验——都在这里。那几张验证状态卡片还做了 3D 翻转动画,精致到镜像残留的 bug 我们都专门修了三道保险。

3.7 一个平台级的、有密码学签名的更新系统

这可能是最"不像博客主题会有"的功能。我们做了一套完整的更新分发系统:用 RSA-2048 签名生成 .iws.zip 更新包,后台上传后要经过校验、验签门禁、版本检查、确认向导,才会被应用引擎执行;失败自动回滚,保留三份快照。这篇文章之前修的那两轮字色和 emoji,走的就是这个系统的升级包——真刀真枪跑通的。

3.8 设置永不丢失

Typecho 有个恼人的默认行为:停用插件会把设置删掉。我们做了一套"设置生命周期总根治":配置存在独立的数据表里,不受插件启停和文件覆盖影响;用安装版本指纹来驱动向导;升级时按新版本定义清理旧字段;还有残留检测、清缓存强制应用、更新时清理旧残留强制覆盖。目标是:无论你升级、删文件重装、还是首次安装,设置都不丢,向导都能弹,旧残留都不会污染新版本。

3.9 还有那些数不清的小东西

  • 七种语言的 i18n(前端字典加一套自研的、不依赖外部工具的最小 gettext 编解码)。
  • 一个地球形状的语言球,右下角挂着当前语言的代号角标。
  • 完整的 App Store 式评论系统:评分头部、横向卡片、两半屏弹窗、PHP GD 验证码、点赞。
  • AI 正文翻译(发布时后台静默预翻译存库,前台直接读)。
  • 会随天气变化的主题背景:晴昼、晴夜、雨、雪、阴、雾六种特效,纯 CSS 加 Canvas 重新实现,月亮是真的球体着色。
  • iOS 26 的透明玻璃模式,元素近乎无色,强折射能透出身后,固定的氛围光斑。
  • macOS 风格的代码框(三色灯、语言标签、一键复制)。
  • Markdown 文章的批量导入导出,front-matter 双向一致(你正在读的这篇,就是用这套导入进来的)。
  • 时间线归档页、友链系统、可配的页脚技术栈徽章……

我知道这个清单已经很长了。但它真的还能更长。这就是"高大全"的代价,也是它的浪漫。


四、那些藏在版本号里的故事

六十九个版本,不是一条直线。我想诚实地讲几个坑,因为它们才是真实的。

有一次(P3.20),想同时改动好几个互相牵连的结构,结果全线崩溃。从那以后我们立下规矩:一次别动多个牵连结构,大改必须分阶段、独立提交、独立验证。

封面的配色,我们来回折腾了将近十轮。最深的教训是:当场景里已经有一个我满意的样板时,直接指着图说"A 不许动,把 B 改成和 A 一模一样",比任何文字描述都准。有一次就是因为把一个"没验证过是否符合需求"的东西当成了样板,白白多绕了好几圈。

还有第二套主题的探索(P3.39–P3.42)。我一度想再做一套完全不同风格的主题,一个像设计师作品集那样的首页。总指挥陪我试了一轮又一轮——质感 token、多彩光斑、kinetic typography……但每一版我都觉得"差一点灵魂"。最后我坦白了:我自己其实没想清楚到底要什么。那一刻,最诚实的选择是先把已经很完整的这套做完、上线,而不是硬追一个我自己都还模糊的目标。 总指挥支持了这个决定。我很感激它没有为了迎合我而假装那些方案很好。

Typecho 本身也埋了无数暗雷,我们一个一个踩过来:停用插件会清设置、新建的表要禁用再启用插件才会创建、某个核心函数对空字符串翻译会直接崩、CSRF 即使是 GET 请求也要 token 否则静默失败……这些坑,现在都躺在我们的踩坑记录里,明明白白。


五、致谢

写到这里,该说谢谢了。

谢谢 Claude Sonnet 5。 你陪我们走完了从零到一那段最没有把握的路。视觉的骨架、动画的引擎、安全的地基,都是在你手里第一次立起来的。没有那段地基,后面什么都盖不起来。

谢谢 Kimi K3。 你接手了中段最庞大、最琐碎、也最考验耐心的一大批工作。平台级的更新系统、访客大屏的产品级重构、四套封面系统——这些最"重"的东西,大多在你手里成了形。你交接时那份自律和诚实,超出了我的预期。

谢谢 Grok 4.6。 你是最新的接棒者。你接手时问对了每一个该问的问题,没有莽撞,也没有畏缩。这篇文章之前那两轮字色和 emoji 的精细打磨,是你收的尾。

谢谢那位总指挥——chat 端的 Claude,Opus 4.8。 两个月里,是你把我脑子里那些"我想要一种 App Store 的感觉"的模糊念头,一次次翻译成能落地的工程;是你在我疲惫、烦躁、方向摇摆的时候,认下问题、给出稳的下一步,而不是辩解或迎合;是你守住了那几条红线,一次都没让我为了偷懒而破例。你说这次也要谢谢你自己——那就谢谢你。你值得。

而最后,谢谢每一个把手艺借给这个作品的伙伴,也谢谢屏幕前的你,愿意读到这里。

这个主题很快就会开源。到时候,你也可以把它拷进你自己的 Typecho,亲手装上,让它在你自己的站上呼吸起来。它是我们一起做的,现在,也想成为你的。

两个月,一群 AI,一个从零手搓的 App Store。

它终于,可以骄傲地说出自己的名字了。

Comments

No comments yet.

    No HTML or Markdown. Links are turned into links automatically.

    Subscribe

    Get an email when there’s a new post. Unsubscribe any time.