简介
从 Discourse 版本 3.2.0.beta3 开始,Discourse 主题/组件可以利用迁移功能来无缝地演进和更改其设置。此功能通过以受控方式处理设置更改,确保主题的更新不会破坏现有安装。
何时使用迁移
迁移特别有用的常见场景:
- 更改设置的类型(例如,从逗号分隔的字符串到列表)。
- 重命名设置。
- 修改存储在设置中的数据的结构或格式。
在这些场景中,如果在 settings.yml 文件中更改了设置类型或名称,而没有相应的迁移,则现有安装中已更改默认值的设置将丢失其更改,并在主题更新时可能损坏。
为确保更新主题设置时的平稳过渡,主题开发者应提供一个迁移,指示 Discourse 核心如何将符合旧版 settings.yml 的现有状态迁移到新版本。
迁移文件
迁移是位于主题的 migrations/settings 目录中的 JavaScript 文件,遵循 XXXX-migration-name.js 的命名约定。XXXX 前缀是版本号,从 0001 开始并按顺序递增,这决定了执行顺序。
名称应是迁移目的的简洁描述,仅限于字母数字字符、连字符,长度不超过 150 个字符。迁移按其版本号的升序执行。
我们建议您为第一个迁移从 0001 开始,为第二个迁移从 0002 开始,依此类推。请注意,如果迁移的版本低于 1000,则必须用前导零填充版本,使其成为 4 位数,因为迁移文件名必须以 4 位数字开头。出于同样的原因,目前一个主题最多只能有 9999 个迁移,但我们将来可能会更改此限制。
迁移函数
迁移可以使用标准的 JavaScript 功能,例如类、函数、数组、映射等。Discourse 核心的唯一期望是每个迁移文件必须导出一个默认函数作为入口点。此函数接收一个 Map 对象,该对象表示已修改的主题设置,并返回一个 Map 对象,该对象反映所有设置所需的最终状态。
示例
重命名主题设置:
// filename: 0001-rename-old-setting.js
export default function migrate(settings) {
if (settings.has("old_setting_name")) {
settings.set("new_setting_name", settings.get("old_setting_name"));
settings.delete("old_setting_name");
}
return settings;
}
此迁移应伴随 settings.yml 文件中的设置重命名。
将逗号分隔的字符串设置转换为正确的列表:
// filename: 0001-convert-string-setting-to-list.js
export default function migrate(settings) {
if (settings.has("list_setting")) {
const list = settings.get("list_setting").split(",");
settings.set("list_setting", list.join("|"));
}
return settings;
}
与前面的示例类似,此迁移应伴随在 settings.yml 文件中将设置类型从 string 更改为 list。
重命名枚举设置的选项:
// filename: 0001-rename-enum-choice.js
export default function migrate(settings) {
if (settings.get("enum_setting") === "old_option") {
settings.set("enum_setting", "new_option");
}
return settings;
}
向列表设置添加新项:
// filename: 0001-add-item-to-list.js
export default function migrate(settings) {
if (settings.has("list_setting")) {
const list = settings.get("list_setting").split("|");
list.push("new_item");
settings.set("list_setting", list.join("|"));
} else {
settings.set("list_setting", "new_item");
}
return settings;
}
执行和错误处理
迁移在主题安装和更新期间自动运行。它们仅执行一次;如果迁移在成功执行后被修改,它将不再运行。如果迁移失败,更新过程将停止,并提供有关发生错误的错误消息。
如果迁移存在导致设置状态损坏的错误,则修复问题的正确方法是创建一个新的迁移来纠正损坏的状态,而不是修改原始迁移。
本文档已进行版本控制 - 在 github 上建议进行更改。