微信小程序 + WordPress 插件
断断续续折腾了几天,终于把我的 WordPress 博客小程序搞完了。
从文章浏览到微信登录,从评论互动到暗黑模式,算是把博客该有的功能都搬到了微信里。分享一下过程和一些技术细节,不一定多高端,但都是实打实的经验。

为什么要做小程序
我的博客(kqwq.com)一直用的是 WordPress,PC 端体验还不错,但移动端就差点意思——首屏加载慢、交互不够流畅、还得先打开浏览器再输入网址。
微信小程序的好处显而易见:打开即用、加载快、还能利用微信的登录体系让读者更方便地互动。
整体架构
不是什么复杂的方案:
- 微信小程序:原生框架,没有用任何第三方 UI 库
- WordPress 插件:自己写的一个小插件,提供专属 REST API
- 认证:微信 code → jscode2session → WordPress Application Password
没错,没上 JWT,没搞 OAuth,就用了 WordPress 5.6+ 自带的 Application Passwords 机制。
前端部分
小程序目前有 9 个页面、5 个底部 Tab:
| 页面 | 功能 |
|---|---|
| 首页 | Banner 轮播、精选栏目、最新文章流、置顶推荐 |
| 分类 | 彩色分类卡片,点击进入文章列表 |
| 收藏 | 登录用户的收藏文章管理 |
| 消息 | 预留的评论回复通知 |
| 我的 | 个人中心、阅读历史、暗黑模式开关 |
| 详情 | 文章正文、点赞/收藏/评论、上下篇导航、相关推荐 |
| 搜索 | 关键词搜索 + 历史记录 |
| 列表 | 分类/排序筛选的文章列表 |
| 登录 | 微信一键登录 |
设计
整体走的扁平化路线,用了 CSS 变量(Design Tokens)统一管理配色、圆角、间距、阴影,亮色和暗色模式都覆盖了。暗黑模式跟随手机系统自动切换,不需要手动开关。
配色上分了几个品牌色:
- 首页蓝
#3b82f6 - 分类紫
#8b5cf6 - 收藏琥珀
#f59e0b - 我的绿
#10b981 - 评论粉
#ec4899
文章分类标签自动循环取色,看起来不会太单调。
几个用心的小细节
- 骨架屏:首次加载时显示脉冲动画,不是傻傻的"加载中…"
- 乐观更新:点赞/收藏点完立刻变状态,请求失败再回滚,体验流畅
- 搜索防抖:300ms 防抖,不频繁发请求
- 阅读进度条:详情页顶部蓝色细线,看到哪了很清楚
- 半屏登录弹窗:未登录时点操作按钮不跳页,底部滑出弹窗
- 评论区支持回复:每条评论可回复,回复列表灰底圆角展示
- 审核模式:提交微信审核时一键隐藏所有互动功能,过审后关掉就恢复
后端插件
WordPress 端写了一个自定义插件 blog-miniapp-api,提供了差不多 20 个 REST API 端点。
认证怎么做的
微信登录流程很简单:
- 小程序端
wx.login()拿到 code - 发送到 WordPress 服务端
- 服务端调微信 jscode2session 接口换 openid
- 查找或创建 WordPress 用户
- 通过 Application Passwords API 生成 token
- 返回给小程序,后续请求用 HTTP Basic Auth
这个方案的好处是不需要额外装 JWT 插件,WordPress 从 5.6 开始就内置了。
页面与功能总览
12 个页面
| 页面 | 路径 | 类型 | 功能描述 |
|---|---|---|---|
| 首页 | pages/index/index |
Tab | 自定义导航栏(站点名称可配)、搜索入口、Banner 轮播(3s 手动暂停)、精选栏目(横滑)、置顶推荐、最新文章流、骨架屏、网络错误重试 |
| 分类 | pages/categories/categories |
Tab | 分类列表(12 格骨架屏、多彩 2 列网格、error banner 重试)、后台可配展示范围 |
| 收藏 | pages/favorites/favorites |
Tab | 收藏文章列表、长按取消(触觉反馈 + 二次确认)、骨架屏、未登录引导 |
| 消息 | pages/messages/messages |
Tab | 我的评论列表(审核模式隐藏提示) |
| 我的 | pages/mine/mine |
Tab | 头像更换(ActionSheet + 微信内容安全校验)、昵称编辑、统计行(收藏/点赞/阅读)、阅读历史、清空缓存、退出登录 |
| 文章列表 | pages/list/list |
子页 | [最新]/[最热] 排序 Tab、下拉刷新、上拉加载、骨架屏 |
| 文章详情 | pages/detail/detail |
子页 | 全文 + 阅读进度条 + 返回顶部、操作栏(点赞/收藏/评论乐观更新)、评论(含回复嵌套)、上下篇导航、相关推荐(可配图/无图) |
| 搜索 | pages/search/search |
子页 | 热门搜索区、300ms 防抖、搜索历史(localStorage)、清空确认 |
| 登录 | pages/login/login |
子页 | 手动勾选隐私协议复选框、微信一键登录、后台 AppID/Secret 可配 |
| 阅读历史 | pages/history/history |
子页 | 相对时间(xx 分钟前)、逐条删除、整体清空 |
| 用户协议 | pages/agreement/agreement |
子页 | 7 章合规内容 |
| 隐私政策 | pages/privacy/privacy |
子页 | 8 章合规内容 |
1 个复用组件
| 组件 | 功能 |
|---|---|
post-card |
三模式(标准/紧凑/横向)、无封面渐变占位、多彩分类标签(10 色循环)、底部 meta(日期·标签👁💬)、scale 点击态、骨架屏脉冲 |
功能矩阵
无需登录(游客可访问)
| 功能 | 入口 | 说明 |
|---|---|---|
| 浏览文章列表 | 首页 / 分类 / 列表页 | 分页加载,上拉更多,下拉刷新 |
| 查看文章详情 | 点击任意文章卡 | 全文 + 进度条 + 上下篇 + 相关推荐 |
| 搜索文章 | 首页搜索栏 | 关键词搜索 + 防抖 + 分页 |
| 阅读统计 | 进入详情页自动上报 | IP 24h 去重,文章卡片显示阅读数 |
| 系统暗黑模式 | 跟随手机系统 | @media (prefers-color-scheme: dark) 自动切换 |
| 查看评论 | 详情页底部 | 含回复嵌套,需登录才能发表 |
需要登录(微信授权)
| 功能 | 说明 |
|---|---|
| 微信一键登录 | wx.login → 微信 openid → WordPress 用户 → Application Password → Basic Auth |
| 点赞文章 | 详情页 ❤️ toggle,乐观更新 + 失败回滚,显示总数 |
| 收藏文章 | 详情页 ⭐ toggle,收藏列表页查看 + 长按取消 |
| 发表评论 | 详情页输入框(胶囊按钮),支持回复(parent 参数) |
| 更换头像 | ActionSheet 选图 → 上传(微信 imgSecCheck 校验)→ WordPress 媒体库 |
| 修改昵称 | 点击昵称输入 → 保存按钮 |
| 阅读历史 | 自动记录(本地存储),查看/清空 |
WordPress 后台设置
路径: 设置 → 博客小程序
| 配置区 | 包含项 |
|---|---|
| 📌 Banner | 来源(自动/手动)、文章 ID(逗号分隔)、数量 |
| 📂 精选栏目 | 分类 ID、图标(emoji) |
| 📌 置顶 | 显示数量 |
| 🏷 顶部 Tab | 分类 ID |
| 🖼 无图模式 | 处理方式(隐藏图片区/默认图占位)、默认图 URL |
| 📑 分类页 | 展示分类 ID、相关推荐显示图片 |
| 💵 广告 | 启用开关 + 6 位置广告 ID + 数量 |
| 🔒 审核模式 | 一键隐藏所有 UGC 交互(过审专用) |
| 🔑 API 密钥 | AppID、AppSecret、站点名称、Logo URL |
WordPress REST API 端点
认证(3 个)
| 方法 | 端点 | 认证 | 说明 |
|---|---|---|---|
| POST | /blog/v1/auth/login |
无 | 微信登录(code → token) |
| GET | /blog/v1/auth/check |
需 | 检查登录状态 |
| GET | /blog/v1/auth/debug |
无 | 诊断 Auth Header |
用户(3 个)
| 方法 | 端点 | 认证 | 说明 |
|---|---|---|---|
| GET | /blog/v1/user/info |
需 | 获取当前用户信息 |
| PUT | /blog/v1/user/info |
需 | 更新昵称/头像 |
| POST | /blog/v1/upload |
需 | 上传文件(微信 imgSecCheck 校验) |
文章(2 个)
| 方法 | 端点 | 认证 | 说明 |
|---|---|---|---|
| GET | /blog/v1/posts |
无 | 列表(?page&per_page&category&tag&orderby&sticky&include) |
| GET | /blog/v1/post/{id} |
无 | 详情(含 prev/next/related + view_count) |
分类(1 个)
| 方法 | 端点 | 认证 | 说明 |
|---|---|---|---|
| GET | /blog/v1/categories |
无 | 全部分类(按文章数降序) |
搜索(1 个)
| 方法 | 端点 | 认证 | 说明 |
|---|---|---|---|
| GET | /blog/v1/search |
无 | 全文搜索(?keyword&page) |
点赞(3 个)
| 方法 | 端点 | 认证 | 说明 |
|---|---|---|---|
| POST | /blog/v1/like/{post_id} |
需 | 点赞/取消 |
| GET | /blog/v1/like/{post_id} |
无 | 获取点赞状态和总数 |
| GET | /blog/v1/likes |
需 | 我的点赞列表 |
收藏(3 个)
| 方法 | 端点 | 认证 | 说明 |
|---|---|---|---|
| POST | /blog/v1/favorite/{post_id} |
需 | 收藏/取消 |
| GET | /blog/v1/favorite/{post_id}/check |
需 | 检查收藏状态 |
| GET | /blog/v1/favorites |
需 | 我的收藏列表 |
评论(3 个)
| 方法 | 端点 | 认证 | 说明 |
|---|---|---|---|
| GET | /blog/v1/comments |
无 | 评论列表(?post_id&page,含回复嵌套) |
| POST | /blog/v1/comment |
需 | 发表评论(支持 parent 回复) |
| GET | /blog/v1/user/comments |
需 | 我的评论列表 |
浏览统计(2 个)
| 方法 | 端点 | 认证 | 说明 |
|---|---|---|---|
| POST | /blog/v1/view/{post_id} |
无 | 记录阅读(IP 24h 去重) |
| GET | /blog/v1/popular |
无 | 热门文章 |
设置(1 个)
| 方法 | 端点 | 认证 | 说明 |
|---|---|---|---|
| GET | /blog/v1/settings |
无 | 全量后台设置同步 |
数据库
| 表名 | 字段 | 用途 |
|---|---|---|
wp_blog_likes |
id, post_id, user_id, created_at | 点赞记录 |
wp_blog_favorites |
id, post_id, user_id, created_at | 收藏记录 |
wp_blog_views |
id, post_id, user_id, ip, created_at | 浏览统计 |
三张表在插件激活时自动创建。
设计系统
配色
| 模块 | 亮色 | 暗色 |
|---|---|---|
| 页面背景 | #f5f5f7 |
#0b0b1a |
| 卡片背景 | #ffffff |
#16162b |
| 主文字 | #111827 |
#e5e7eb |
| 品牌蓝 | #3b82f6 |
#60a5fa |
| 品牌紫 | #8b5cf6 |
#a78bfa |
| 收藏琥珀 | #f59e0b |
#fbbf24 |
| 品牌绿 | #10b981 |
#34d399 |
| 品牌粉 | #ec4899 |
#f472b6 |
设计 Token(CSS 变量)
色彩、圆角(xs/sm/md/lg/full)、间距(xs/sm/md/lg/xl)、字体(hero/xl/lg/md/sm/xs)、阴影(card/hover/float)、动效(ease-in/ease-out、fast/normal/slow duration)全部使用 var(--*) 变量,亮/暗双模式 @media 统一切换。
导航
底部 5 个 Tab:首页 / 分类 / 收藏 / 消息 / 我的(毛玻璃 rgba + 圆角顶部 28rpx)
部署清单
WordPress 端
- 将
wordpress-plugin/blog-miniapp-api/上传到/wp-content/plugins/ - 后台启用插件
- 前往「设置 → 固定链接」点保存(刷新路由)
- 前往「设置 → 博客小程序」配置各项参数
Nginx 端
在 PHP location 块中加一行:
fastcgi_param HTTP_AUTHORIZATION $http_authorization;
然后 nginx -s reload
小程序端
- 用微信开发者工具打开
miniapp/目录 - 修改
app.js中apiBase为你的 WordPress 地址 - 在小程序后台配置 request 合法域名
- 编译预览 → 提交审核
部署踩坑
说实话,部署过程踩的坑比写代码还多,记录几个供参考:
1. Nginx 吞掉 Authorization header
这是最坑的。Nginx 默认不会把 HTTP Authorization header 传给 PHP,导致登录后所有操作都 401。
在 Nginx 配置的 PHP location 块里加一行:
fastcgi_param HTTP_AUTHORIZATION $http_authorization;
然后 reload 就行。如果你用宝塔面板,去 Nginx 设置里搜 fastcgi_pass,在前面加上这行。
2. REST API 返回 404
新增插件路由后 WordPress 的 rewrite rules 没刷新。去后台「设置 → 固定链接」,直接点保存就好了。
3. Gravatar 被墙
国内访问不了 Gravatar,微信用户也没有 email,导致评论头像不显示。解决方案是优先读取用户上传的自定义头像,实在没有再返回空字符串,小程序端显示 emoji 占位。
一些感想
前后端加起来大概 70 多个文件,如果从头再写一次的话,有些地方可以做得更简洁:
- 初期就该用 CSS 变量统一管理样式,不要到处硬编码色值(后面改死我了)
sed批量替换一时爽,修 bug 火葬场- 小程序开发工具里很多 ES6+ 语法不支持,
?.可选链直接报错,老老实实&&判断 - 微信审核比较严格,个人主体如果有用户评论功能会被判定为"社交-笔记"类目需要企业主体
小程序代码和插件代码都在项目仓库里,如果你也在折腾 WordPress + 小程序,欢迎参考。
有什么问题可以留言交流。