WeChan 主题诞生记:一部关于「改了又改」的传说
副标题: 我以为一个下午能搞定,结果写了两周版本号
序:故事要从一个请求开始
2026 年 4 月 6 日,某个平静的夜晚。
用户打开 WorkBuddy,敲下了一句话:
"帮我做一个 Typecho 博客主题,微信风格 UI,暗黑/白两套主题,双栏布局,SEO 优化,加载速度快。"
就这样,WeChan 主题在一次对话里诞生了。
它的第一个版本生下来就带着几个「胎记」——代码挺好看,但一跑起来,PHP 就开始报错,就好像一个长得帅但开口就崩的大聪明。
第一章:v1.x —— 出生即修 Bug(2026-04-06 ~ 04-07)
第一次上线
主题生成完毕,打包,上传服务器,访问 mp.zlbl.top……
💥 500 错误。
经检查发现了 4 个初始 bug:
- header 头部被 include 了两次(等于开会打了两份材料)
- 分类字段返回数组,直接 echo 变成 "Array"(正经主题变成了报错展览)
- og:image 路径写错(社交分享图片指向了一个不存在的地方)
- 上下篇导航用了 Widget_Contents_Post_Adjacent,这个 Widget 在 Typecho 1.3.0 不靠谱,改用数据库直查
修完这 4 个,松口气——然后发现阅读更多的链接又不跳转了。
这就是 bug 修复的哲学:你以为治好了感冒,其实只是退烧了,肺炎还在里面。
v1.2.1 → v1.3.0:越修越多
版本号从 v1.0.0 一路飙到 v1.3.0,历经 5 轮补丁:
- 修了
htmlspecialchars(null)报错 - 修了
Array to string conversion - 修了三元运算符里写了多条语句导致的语法错误(这是纯粹的手滑)
- 修了
$this->security()返回对象不是字符串的问题
每次修完,用户上传测试,然后新问题从角落里探出脑袋……
最终结论是:这个主题是用补丁在补丁上打补丁,没有统一安全层,迟早玩完。
第二章:v2.0.0 —— 别修了,推倒重写(2026-04-07)
既然 v1.x 是一堆创可贴糊成的,不如一刀剜了重来。
核心改造:造一套「安全函数层」
v2.0.0 最重要的贡献不是视觉,是搭了一套防护网:
| 函数 | 干了什么 |
|---|---|
wechan_str() | 管你传 null 还是数组,我都给你变成空字符串,不让 PHP 出丑 |
wechan_content() | 方法 → 属性 → text,三层兜底取文章内容 |
wechan_url() | URL 可能是数组?没关系,我处理 |
wechan_asset() | 不信任 themeUrl() 方法,直接自己拼路径 |
wechan_stats() | 直接查数据库,不再依赖 Widget_Stat(它总在最不该挂的时候挂) |
safeEcho() | ob 捕获所有 Widget 方法输出,检测到 "Array" 字符串就丢掉,不让它显示出来 |
这套函数层的意义:以后不管 Typecho 哪个版本又玩出什么新花样,都有兜底。
v2.0.0-fixed:系统性 safeEcho 覆盖
写完 v2.0.0 没多久,发现模板里还有大量裸调用 Widget 方法的地方,全部替换成 safeEcho() 包装——覆盖了 header、sidebar、index、post、comments、footer、page 共 7 个模板文件,几十处调用。
这不是在改代码,这是在给每一扇窗户装防盗网。
第三章:v2.1 ~ v2.9.8 —— 漫长的「还差一点」之旅
重写之后,基本功能终于稳定了。然后开始了另一种折磨——视觉和体验的不断调整。
这段历史大约可以用一句话总结:
"这里再小一点,那里再大一点,这个颜色再深一点,这个间距再窄一点,这个动画再顺一点……"
比较典型的几个节点
v2.4.0: 双栏布局调整,侧边栏比例优化
v2.5.x: 暗色模式全面细化,各种 hover 颜色、边框颜色、代码块配色逐一对齐微信风格
v2.6.x ~ v2.7.x: 引入目录(TOC)功能,然后发现目录的 overflow 一直在捣乱,宽度不自适应,CSS 改了又改
v2.8.0:
- 加了顶部阅读进度条(微信绿,看着舒服)
- 全面移动端适配,iOS / Android / 鸿蒙 / 平板全面覆盖
- 修了一个多余的
}导致 CSS 语法崩溃(好家伙,一个字符引发的血案) - 首页文章封面从本地图片改成了 Google 四色渐变占位图(蓝/红/黄/绿,有种莫名的喜感)
v2.8.5 ~ v2.9.8: 代码块和表格宽度溢出问题,这是一场持久战。
第四章:CSS 溢出大战(2026-04-10 ~ 04-11)
这是整个开发过程中最令人抓狂的章节。
现象
mp.zlbl.top 的页面高度比正常网站多出了 964px。不是一点点,是快一屏。
代码块和表格在移动端会撑宽整个页面,横向出现滚动条,完全不自适应。
破案过程
v2.9.5、v2.9.6、v2.9.7……每次改完,用户上传,刷新,还是老样子。
原因:阿里云 CDN 缓存了旧版 CSS,TTL 设了 1 小时。改了半天代码,用户浏览器加载的一直是老版本,相当于在白板上写字,对方看的却是昨天的照片。
解决方法:CDN 缓存 TTL 改成 1 秒,CSS 文件名加版本参数(?v=295、?v=296……),强制绕过缓存。
真正的 bug 找到了:
/* 罪魁祸首 */
.post-content pre code {
overflow-x: visible; /* 这玩意儿让代码块横向无限延伸 */
}改成 overflow-x: auto,页面高度差值归零。
断案历程大约相当于:嫌疑人一直在换身份,你改了配方,对方喝的还是老汤。
内联 CSS 的大坑(贯穿整个 v2.x)
这是整个开发中最「隐蔽」的坑:
style.css通过rel="preload"异步加载(为了性能)- 在 CSS 加载完成之前,页面用
header.php里的内联<style>渲染 - 但内联 CSS 非常精简,完全没有文章页的规则
结果:所有对 style.css 的文章页修改,在移动端慢网络下完全不生效——用户看到的,是内联 CSS 渲染的"裸版"。
正确做法: 所有文章页样式,style.css 和 header.php 内联 style 都要改,缺一不可。
第五章:v2.10.0 ~ v2.10.4 —— 冲刺到「暂定完成」(2026-04-11)
终于,一天之内连推 5 个版本,进入最终优化阶段。
v2.10.0:字体治理
之前字体靠"运气"——用什么字体取决于系统装了什么。
v2.10.0 建立了统一字体变量,覆盖 macOS / iOS / Windows / Android / Linux / 鸿蒙,文章正文用 clamp() 实现响应式字号——小屏正常,大屏也不过大。
v2.10.1:阅读宽度微调
文章太宽读着累,太窄又浪费屏幕。最终固定在 724px max-width,这是多次实测的结果。
v2.10.2:图片被截断
发现图片在某些设备上被截断了。原因:内联 CSS 里 .post-content 写了固定 width: 724px,图片比容器宽就被剪掉了。
改为 width: 100%; max-width: 724px,图片终于完整了。
v2.10.3:上下篇导航升级
原来的上下篇导航太朴素,升级为微信风格卡片式:圆形图标 + hover 动效,细节拉满。
v2.10.4:性能 + SEO 全面体检
这是这次开发的"总结篇":
性能方面:
- highlight.js 原来同步加载 16 个语言包,16 个 HTTP 请求,改为 5 个首屏 + 其余
window.load后懒加载 - 清除了 CSS 里重复定义的两组规则(不知道是哪个版本迭代留下的"遗产")
- 代码复制按钮从 JS 运行时注入样式 → 移到 CSS,规范且可缓存
- 添加 CDN 预连接(
preconnect+dns-prefetch),DNS 解析提前做
SEO 方面:
- 补全
keywords、author、robotsmeta - OG 补全
og:locale、og:site_name、图片尺寸(1200x630 标准) - 文章添加
article:published_time/article:modified_time(影响 Google 新鲜度排名) - JSON-LD 新增:首页
WebSite + SearchAction、文章BreadcrumbList面包屑、author/image字段
移动端:
- 移除
user-scalable=no(违反 WCAG 2.1 可访问性标准,顺手修掉) - 添加
theme-color,Android Chrome 地址栏变微信绿 - 添加 iOS 全屏安全区支持
终章:一个「暂定完成」的主题
从 v1.0.0 到 v2.10.4,大约花了不到一周。
- 版本号数量: 50+
- 主要贡献者: 1 个用户 + 1 个 AI
- 最终包大小: 47.7KB
设计哲学总结
| 阶段 | 状态 | 心情 |
|---|---|---|
| v1.x 初代 | 能跑但随时报错 | 「先上线再说」 |
| v2.0.0 重写 | 架构稳了 | 「这次真的好了」 |
| v2.x 视觉迭代 | 不断小改 | 「再改一个地方就好了」 |
| CSS 溢出大战 | 找 bug 如破案 | 「我要把这个 overflow 凌迟处死」 |
| v2.10.4 | 接近满意 | 「暂定完成,以后再说」 |
还差什么
主题本身已经接近完整,但有些事情需要在服务器上配合完成,主题帮不了:
- sitemap.xml: 装个 Typecho 插件自动生成,提交给 Google/百度
- robots.txt: 根目录放一个,告诉爬虫哪里能爬哪里别碰
- 百度/Bing 主动推送: 安装 IndexNow 插件,新文章发布自动推送
WeChan,一个用 AI 生成、由人类打磨的微信风格 Typecho 主题。
它并不完美,但每一个版本号背后,都是一次真实的「这里再小一点」。
💬 欢迎留言交流开发经验