内容版本控制是 Keystone 团队在内部讨论过很多的东西,但这是一个相当复杂的领域。有很多不同的方法来解决这个问题,即使是在单个项目中进行版本控制时也是如此。如果您将关系引入其中并跨多个项目进行版本控制,问题空间会迅速扩大。
如果第一方解决方案做过构建它可能会构建在“Keystone 之上”——类似于 @keystone-6/auth package——也就是说,一个单独的、可配置的包,它使用记录在案的 Keystone API 来添加功能。无论如何,就目前的情况而言,版本控制和发布工作流是您需要自己设计和构建的。
我的建议是首先明确您需要版本化的内容和不需要的版本。需要考虑的事项:
- 您需要对整个项目进行版本控制还是只需要对几个字段进行版本控制?
- 您是否需要更改历史记录,或者拥有一个“已发布”版本和一个可选的可编辑“草稿”版本就足够了吗?
- 您是否需要“还原”更改,或者“仅更新”模型是否足够?
- 您关心相关项目吗? (例如,假设您的博客帖子与
Tags 列表相关,编辑标签是否构成帖子的新“版本”,或者是版本化部分的“外部”?)
- 合作怎么样;会有多人同时尝试编辑一篇文章/草稿吗?
- 可以有多个草稿版本还是只有一个?
- 您是否需要考虑预览更改或(更糟糕的)更改集?
- 您是否需要某种集成的批准工作流程,或者任何创建内容的人都可以发布/恢复它吗?
我想到了一些基本方法:
草稿/发布字段
对于像博客文章这样相对简单的内容,您也许可以在项目中在字段级别实施草稿/发布的工作流程。像这样:
Post: list({
fields: {
slug: text({ validation: { isRequired: true }, isIndexed: 'unique' }),
publishedTitle: text({ validation: { isRequired: true } }),
publishedBody: document({ /* ... */ }),
draftTitle: text({ validation: { isRequired: true } }),
draftBody: document({ /* ... */ }),
},
// access, hooks, etc.
}),
您的前端仅显示 published... 字段,但您将后端限制为仅允许编辑 draft... 字段(您甚至可以从管理 UI 隐藏已发布的字段)。可以添加挂钩或自定义突变以通过在字段之间复制来“促进”草稿内容发布。通过正确的访问控制,您甚至可以设置前端以使用神奇的 URL 参数或其他东西来预览草稿内容 institchu。
它非常基本,但易于设置和使用。
每个版本的项目
一个更强大的替代方案是用单独的项目表示版本,并使用一个字段来跟踪哪个版本是当前发布的内容:
Post: list({
fields: {
slug: text({ validation: { isRequired: true }, isIndexed: true }),
title: text({ validation: { isRequired: true } }),
body: document({ /* ... */ }),
isPublished: checkbox(),
},
// access, hooks, etc.
}),
在这种情况下,slug 字段在列表中不是唯一的——每个帖子可以有多个项目,代表即将到来的草稿或历史版本。当发布一个版本的帖子时(通过将 isPublished 设置为 true),一个钩子确保任何具有相同 slug 的项目都将 isPublished 标志设置为 false。前端只需通过isPublished 进行过滤即可获取当前版本(如果需要,可通过访问控制强制执行)。这使您既可以发布更新又可以回滚到任何以前的版本。它还在某种程度上解决了关系——例如。如果您有 Tags 的相关列表,与 Posts 多对多链接,则对帖子标签的更新与内容一起进行版本控制。
为了使工作流程顺畅,拥有一个复制现有帖子的自定义突变可能会很有用,这样您就可以轻松地对现有内容进行更改。也许还有一个自定义的管理 UI 页面,以帮助可视化帖子历史记录和管理恢复操作等。
这些只是两个例子,但还有许多其他方法可以解决这个问题。只要明确您的要求,然后做最简单的事情! :)