About dby-theme
A skill for creating and updating themeJson styles for WeChat Official Account articles. It supports local validation and preview before saving a theme to the server as the default.
Key features
- 01Generate and edit themeJson
- 02Validate themes locally
- 03Preview rendered HTML
- 04Save a server-side default theme
- 05Back up themes before changes
Use cases
- 01Adjust article colors and heading styles
- 02Preview WeChat formatting before publishing
- 03Set a default theme for future rendering
MCP support
Uses the Doubaoya theme CRUD and render API to retrieve, save, and render themes. It does not describe an MCP server.
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ zizhanovo/ doubaoya-community --skill dby-themeAfter installing, type/dby-themein Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
.versionevals/triggers.jsonlreferences/crud.mddeploy-scope.mdlive-preview.mdtheme-schema.mdscripts/validate-theme.mjsthemes/theme.example.jsonDetails
From the project README公众号排版主题工作室(都爆鸭)
排版是一份声明式的 themeJson(配色 palette + 每个标签的 inline-style 模板),渲染器按它把
Markdown 确定性地渲成公众号内联样式 HTML。按描述生成 / 修改合法的 themeJson,
本地自检 + 预览,再存回服务端设为默认;发文钉了 --theme / config.mdTheme 时再落一份本机文件。
渲染 / 存主题都免费不扣点。
⚠️ 四条硬红线(先读,全程守住)
红线 1 · 微信兼容:标题装饰只能挂在有文字的元素自身
公众号编辑器会 strip 掉没有文字、纯靠 inline-block 宽高 + background 撑色块的空 <section>/<span>。
标题引导条 / 强调竖条 / 下划线必须作为 inline style 直接写在标题元素自身,绝不用独立的空装饰块。
- ✅ 对:
elements.h2.style里直接写border-left:4px solid {{accent}};border-bottom:1px solid {{border}};padding:0 0 8px 11px; - ❌ 错:用
wrapBefore注入一个空的<section style='width:32px;height:4px;background:…'>当色条(无文字 → 被 strip)。
红线 2 · 微信兼容:别给整篇套 decorations.articleWrap 外框
decorations.articleWrap 包整篇正文的浅底圆角卡片在公众号里会变成一道突兀的边框。
articleWrap.before / after 留空字符串;「呼吸感」用段间距(margin / line-height)和局部卡片(如 blockquote 圆角卡)实现。
红线 3 · 安全:themeJson 会内联进公众号草稿,服务端会拒收不合法主题
服务端 POST/PUT/render 都会 validateTheme,不过直接 400。生成后先跑
scripts/validate-theme.mjs 自检——具体校验规则(顶层键、
palette/page 必填字段、style 禁写清单、体积上限)以它为准,不在这里另存一份会漂移的清单。
微信编辑器官方规范另有八条「不拒但走样」的写法(position、text-align:start、固定像素宽、自定义字体栈、文字底下铺渐变…),
清单与可读性基线见 references/theme-schema.md 末尾;校验器对其中四条打 warning。
红线 4 · 数据安全:动手改前必须落盘备份,没有备份不改
改主题是就地覆写(PUT / POST + isDefault:true),服务端不保留历史版本,改坏了没有第二处能找回。
第 1 步的 GET 命令已经把落盘备份写进命令本身——照抄不删;备份文件路径记下来,改坏了照
references/deploy-scope.md「回滚」一节把它 PUT 回去。
契约:服务端主题 CRUD + 渲染(以 doubaoya.com 主仓 render-routes.ts 为准)
⚠️ 先读 dby-gateway/references/protocol.md 再发请求(鉴权、密钥怎么拿、
信封与报错码全在那一份)。本 skill 自己的六条主题路由(GET/POST /api/wechat/theme、
GET /api/wechat/themes、POST /api/wechat/render、PUT/DELETE /api/wechat/theme/:id)
的请求体与返回 → 读 references/crud.md,不需要就别读。
export DOUBAOYA_API_KEY="dyh_你的密钥"
BASE="${DOUBAOYA_BASE_URL:-https://doubaoya.com}"
AUTH="Authorization: Bearer $DOUBAOYA_API_KEY"
render 的主题解析优先级 themeJson(传了就用这份)> themeId >
我的默认主题 > 兜底 benya-clean,所以预览编辑中的主题就传 themeJson;
一人一默认,isDefault:true 时服务端在事务里把我其他主题的 isDefault 置反。
闭环步骤
1. 读起点主题并落盘备份(红线 4,照抄不删)
# a) 读我当前的默认主题(有就在它上面改)并强制落盘备份——主题体在 data.theme.themeJson
BACKUP="/tmp/dby-theme-backup-$(date +%s).json"
curl -s -H "$AUTH" "$BASE/api/wechat/theme" | tee "$BACKUP"
echo "已备份到 $BACKUP —— 改坏了见 references/deploy-scope.md「回滚」一节"
# b) 或列出内置主题,挑一个复制起步(推荐 benya-clean——已按红线 1 / 2 改造过)
curl -s -H "$AUTH" "$BASE/api/wechat/themes"
本 skill 也自带一个 WeChat-safe 起手模板
themes/theme.example.json(暖橘编辑风,复制改配色即可)。
2. 按用户口语描述改 themeJson
把「换成暖橘色 / 标题要竖条 / 引用做成卡片 / 字再大一点 / 排版长得像某某号」翻译成合法 themeJson。
字段全貌见 references/theme-schema.md;守住上面四条红线。改配色最省事:只动 palette 八个键。
3. 本地先自检
把生成的主题写成本地文件,过本 skill 自带的零依赖校验器:
node scripts/validate-theme.mjs /tmp/my-theme.json # 有硬错误按提示改;exit 0 = 合法
4. 预览(改一版看一版)
API 渲染 → 存本地 .html 打开:
# 用编辑中的 themeJson 渲染样例文章,拿回 HTML 存本地打开肉眼看
curl -s -H "$AUTH" -H 'Content-Type: application/json' \
-d "$(jq -n --arg md "$(cat sample.md)" --slurpfile t /tmp/my-theme.json \
'{markdown:$md, title:"预览", themeJson:$t[0]}')" \
"$BASE/api/wechat/render" | jq -r '.data.html' > /tmp/preview.html
open /tmp/preview.html # macOS;别的平台用浏览器打开
sample.md别带#一级标题:title会被插成 h1,正文再有就显示两个大标题。 render 返回的 HTML 与最终存进草稿的正文逐字一致。data.warnings若有(如未知{{token}})一并看一眼。
→ 本机已装 dby-publish 且想在本机「改文件重跑即换肤」地预览,读 references/live-preview.md,
不需要就别读。改 themeJson 本身以上面 API 渲染那条路为准。
5. ⚠️ 落地生效范围(两条渲染路的主题源)
→ 主题调好、要存回去时读 references/deploy-scope.md——它回答「存了之后哪条路会变、
哪条不会」,并给出存回服务端 / 落本机文件 / 改坏了回滚的完整命令。
存回服务端设为默认是主路(POST/PUT + isDefault:true):doubaoya.com 网页排版
工作室、POST /api/wechat/render、以及未钉本机主题的 dby-publish 发文都读它。
仍需落一份本机 theme 文件的只有三种情形:发文时钉着 --theme / config.mdTheme、
离线或拉取失败要兜底、用的是不带自动拉取的旧版 pipeline。
落完向用户汇报时如实说清各自的生效范围,别混着说。
themeJson 结构(速查)
→ 真要动手写 / 改 themeJson 的字段时读 references/theme-schema.md(top-level 键、
elements 支持的标签、{{token}} 插值、li.marker / img.figureStyle / hr.html 这些位置),
不需要就别读。只换配色的话改 palette 八个键就够,其余用 {{token}} 自动跟随。
主题契约以本包
scripts/validate-theme.mjs为准(跑它,别照文档记); 本 skill 的references/theme-schema.md+themes/theme.example.json足够独立完成一次改主题。
下一步(先看用户要的终态是什么)
别默认往下推——用户要的终态停在哪一档,就在哪一档收手:
| 用户要的终态 | 到这一步够不够 | 下一步 |
|---|---|---|
| 只要把默认排版改成自己想要的样子 | ✅ 够了,到这里就结束(以后每次渲染自动生效) | — |
| 还要用这套主题排版某篇正文、存进自己公众号草稿箱 | 不够 | dby-publish(存回服务端的默认排版它会自动拉;本机主题文件用 --theme 指过去) |
| 已有排好版的图文,只想让它进草稿箱 | 不够 | dby-publish |
| 正文还没写 | 不够 | dby-api(拉同主题爆文样本再写正文,走 api.gzh.hotArticle) |
| 正文没过违禁词 | 不够 | dby-banned-words(三平台一次比对,出安全改写版) |
| 说不清要到哪一步 | — | dby(公众号飞轮的逐跳导航) |