Docs / 主题依赖与版本

主题依赖与版本

有些主题只有在某些插件启用时才能正常工作(例如依赖 multilang 提供多语言路由)。GoPress 支持主题在 theme.toml声明式地依赖插件,由 core 解析并强制。

这是模块级依赖:主题按 slug 声明"我需要整个某插件模块",但运行时代码仍只通过 core 的通用扩展点(Hook/Filter/funcmap 等)间接受益,不 import、不调用、不引用插件内部。依赖方向仅限 主题 → 插件,不支持插件依赖插件。

声明语法

theme.toml 里加一个 [requires] 段:

[requires]
core = ">=0.7.0"                      # 可选:要求的 GoPress 核心版本(semver 约束)
plugins = [
  { slug = "multi-language", version = ">=2.0.0" },
  { slug = "seo-extras",     version = "^1.0.0", optional = false },
]
  • slug — 被依赖插件的运行时标识(即插件的 Name(),也写在插件 plugin.toml[plugin].slug)。注意 slug 可能与插件目录名不同(如目录 multilang 的 slug 是 multi-language)。
  • version — 可选的 semver 约束(>=2.0.0^1.0~1.2>=1 <2 等)。留空表示任意版本。
  • optional — 为 true 时,依赖不满足只告警、不阻止主题启用。
  • core — 可选,对核心版本的约束。

强制版本化

主题与插件的版本号必须是合法 semver,且来源单一

  • 主题版本来自 theme.toml [theme].version(主题用 //go:embed theme.tomlBaseTheme 解析,主题不要在 Go 里再写一遍)。
  • 插件版本来自 plugin.toml [plugin].version(插件用 //go:embed plugin.toml)。

两者的 toml 都通过 //go:embed 烤进二进制、读取方式一致:改了代码就必须改对应 toml 的版本号,否则二进制里带的是旧版本号。

core 在构建期gopress gen/build)和启动期都会校验版本是合法 semver。

依赖的四种状态

状态 含义 处理
已满足 插件已编译进来、已激活、版本符合约束 放行
未激活 已编译进来、版本 OK,但未启用 可自动激活(切主题时提示并启用)
版本不符 已激活但版本不满足约束 阻断(显示需要 vs 当前版本)
缺失 根本没编译进这个构建 硬阻断(见下方"编译期现实")

编译期现实(与 WordPress 的关键区别)

GoPress 的插件是编译进二进制的,没有运行时安装。所以"缺失依赖"无法在运行时补救——必须把该插件加入构建后重新 gopress build。后台不会有"一键安装",只会有"自动启用已编译进来但未激活的插件"。

什么时候强制、怎么表现

  1. 构建期 gopress gen/build:扫描每个主题的 [requires],对缺失插件、非法 semver、不满足的版本约束打印告警。
  2. 启动期:解析当前激活主题的依赖——未激活的所需插件自动启用;缺失/版本不符则站点照常启动,但后台顶部显示告警横幅
  3. 切换主题:切换前预检目标主题依赖。
    • 未激活依赖:切换按钮的确认框会列出"将同时启用的插件",确认后事务化切换(先启用插件再切,失败回滚)。
    • 缺失/版本不符:卡片显示红色"依赖缺失"徽章,切换按钮被禁用,悬停显示原因。
  4. 停用插件:若当前激活主题依赖某插件,该插件的"停用"按钮被禁用并提示"被主题依赖,请先切换主题再停用"。

给插件作者:plugin.toml 的 slug

要被主题依赖,插件的 plugin.toml 必须声明 slug,且与插件的 Name() 一致

[plugin]
slug = "multi-language"   # 运行时标识;主题按此 slug 依赖;必须等于 Name()
name = "Multi-Language"   # 人类可读显示名
version = "2.0.0"