主题契约(v1)
主题契约(v1)
工程契约摘要。权威全文:仓库 docs/theme-contract.md、docs/adr/0002-theme-host-boundary.md。契约状态:Locked v1。
版本锁
| 常量 | 位置 | 当前 |
|---|---|---|
| THEME_CONTRACT_VERSION | @inkless/theme-host | "1" |
| THEME_CONTRACT_SUPPORTED | 同左 | ["1"] |
| 主题声明 | ThemePlugin.contractVersion + inkless.theme.json | 必须受支持 |
- 主题声明 contractVersion;Host register 时 assert 兼容。
- 缺省 contractVersion 仅在 Host 仍支持
"1"时按"1"(legacy UMD 宽限)。 - 破坏性 facade 变更 → bump 主版本并更新 SUPPORTED。
- 加法 export 可留在同主版本,仍更新 inventory。
分层铁律
- 主题不得拥有写入 DB 的业务模型(文章、用户、权限…)。
- Host 不得把某一种站点类型的叙事/固定 IA 当作平台默认。
- 实例数据不得写死在主题源码(禁止定稿营销长文当唯一数据源)。
判定树:换主题后数据是否仍在?→ Host。换站点类型是否必须变?→ 主题。多主题复用?→ Host 原语。
路由归属
| 模式 | 所有者 |
|---|---|
/、主题声明 slug | Theme pages[] |
/blog、分类/标签 | Host |
/admin/*、/setup、/auth | Host |
/p/* | Host + sections |
| Docs / GitHub 外链 | theme settings / site config |
冲突优先级(高→低):Host system → blog/taxonomy → theme pages[] → /p/:slug → 外链。
Host facade 白名单
主题只能依赖 @inkless/theme-host + public API,禁止 deep-import @/…。
| Export | 用途 |
|---|---|
| BaseSiteHeader / BrandMark / HeaderUtilities | Chrome 壳 |
| useBranding / useThemeSettings / useThemePages | 品牌与配置 |
| useGlobalConfig / useLocaleMode / useSEODefaults | 站点与 SEO |
| SeoHead / BlogPageShell / ArticleList | 页面原语 |
| getPublicArticles / pickLocaleValue | 数据与 i18n |
| THEME_CONTRACT_* / assertThemeContractCompatible | 契约 |
完整 inventory:frontend/src/theme-host/exports.inventory.ts。
Tokens
使用 Host CSS 变量(ThemeProvider 注入),组件内勿硬编码品牌色(装饰 monogram 除外,可 fallback var(--color-on-surface))。必填组:colors、fonts、layout。Host 用站点已发布主题配置覆盖主题默认。
切换主题
| 保留 | 变化 |
|---|---|
| 文章、媒体、identity/brand | 主题 pages 结构与默认 nav |
| 用户已有 page content | seed 新主题页不覆盖用户内容 |
| 旧主题专用 section | fallback 展示,不删配置 |
Non-goals
- 主题自带 React 副本
- 主题持密钥调 admin API
- 个人站文案写死在主题源码
检查清单(作者)
- contractVersion 与 Host 一致
-
无
@/deep import;只用 theme-host - pages[] 声明一级 IA;扩展页不冒充主题形态
- section type 有主题前缀
- 空/缺失 props 可降级
- UMD 构建 + host smoke 通过
- README:受众、routes、default Features、content schema