草稿
Payload 的 Draft(草稿)功能基于 Versions(版本)功能构建,允许你对 collection 文档和 globals 进行更改,但仅在准备就绪时发布。这一功能让你能够为数据构建强大的预览环境,在发布文档前确保更改效果符合预期。
草稿功能需要启用 Versions 才能正常工作。
通过启用带草稿的 Versions,你的 collections 和 globals 可以维护文档的_更新_且_未发布_版本。这非常适合需要处理文档、更新并保存进度,但不一定立即公开发布的情况。在构建预览实现时,草稿功能极为有用。
如果启用了草稿功能,常规的保存按钮会被替换为新的操作选项,允许你保存草稿或直接发布更改。
选项
Collections 和 Globals 都支持相同的配置选项来启用草稿功能。你可以将 versions.drafts
设为 true
,或者传入一个对象来配置草稿属性。
草稿选项 | 描述 |
---|---|
autosave | 启用 autosave 可以在编辑文档时自动保存进度。设置为 true 或传入包含选项的对象来启用。 |
schedulePublish | 允许编辑者安排未来的发布/取消发布事件。了解更多 |
validate | 将 validate 设为 true 可以在保存时验证草稿文档。默认为 false 。 |
数据库变更
在 collection 或 global 上启用草稿功能后,Payload 会自动向你的 schema 中注入一个新字段 _status
。_status
字段由 Payload 内部使用,用于存储文档是处于 draft
还是 published
状态。
Admin UI 状态指示
在 Admin UI 中,如果启用了草稿功能,文档会显示以下三种"状态"之一:
- 草稿 - 如果文档从未发布过,且只存在草稿版本
- 已发布 - 如果文档已发布且没有更新的草稿可用
- 已变更 - 如果文档已发布,但存在尚未发布的新草稿版本
草稿 API
如果在你的 collection 或 global 上启用了草稿功能,REST、GraphQL 和 Local API 都会发生重要且强大的变化,允许你指定是与草稿还是已发布的文档进行交互。
更新或创建草稿
如果在 collection 或 global 上启用了草稿功能,REST、GraphQL 和 Local API 的 create
和 update
操作会暴露一个名为 draft
的新选项,允许你指定是在创建/更新草稿,还是直接将更改发送到已发布的文档。例如,如果你向 REST 的 create
或 update
操作传递查询参数 ?draft=true
,你的操作将被视为创建 draft
而非已发布的文档。默认情况下,draft
参数设置为 false
。
必填字段
如果在创建或更新文档时启用了 draft
,所有字段都将被视为非必填,这样你就可以保存不完整的草稿。
读取草稿与已发布文档
除了 create
和 update
操作中的 draft
参数外,find
和 findByID
操作也暴露了 draft
参数。
如果在读取文档时将 draft
设置为 true
,Payload 会自动用最新的草稿替换返回的文档(如果有更新的草稿可用)。
例如,考虑以下场景:
- 你创建了一个新的 collection 文档并立即发布
- 然后你进行了一些更新,并将这些更新保存为草稿
- 接着你又做了一些进一步的更新,并保存为另一个草稿
在这种情况下,你的主 collection 中将有一个已发布的文档,同时在 _[collectionSlug]_versions
数据库 collection 中会有两个更新的草稿。
如果你只是通过 find
或 findByID
操作获取创建的文档,系统会返回已发布的文档,而草稿将被忽略。
但是,如果你将 draft
参数设为 true
,Payload 会自动用最近保存的 version
内容替换已发布文档的内容。在上述场景中,由于我们创建了两个版本,Payload 会返回最新(第二个)草稿的数据,你的文档将显示为最近保存的草稿版本,而不是已发布的版本。
重要提示: 单独的 draft
参数不会阻止 API 返回 _status: 'draft'
的文档。你需要使用访问控制来防止未认证用户获取 _status: 'draft'
的文档。阅读下文了解具体实现方式。
控制谁可以查看 Collection 草稿
如果你使用草稿功能,必须考虑谁可以查看草稿,谁只能查看已发布的文档。幸运的是,Payload 使这一过程变得极其简单,并将控制权完全交到你手中。
限制草稿访问权限
你可以使用 read
访问控制 方法来限制谁可以查看文档的草稿版本,只需返回一个查询约束来限制任何给定用户可以检索的文档范围。
以下是一个利用 _status
字段要求用户必须登录才能检索草稿的示例:
import type { CollectionConfig } from 'payload'
export const Pages: CollectionConfig = {
slug: 'pages',
access: {
read: ({ req }) => {
// 如果有用户登录
// 允许他们检索所有文档
if (req.user) return true
// 如果没有用户登录
// 限制返回的文档范围
// 仅返回 `_status` 等于 `published` 的文档
return {
_status: {
equals: 'published',
},
}
},
},
versions: {
drafts: true,
},
//.. Pages 配置的其余部分
}
关于向现有集合添加版本功能的注意事项
如果你已经有一个包含文档的集合,并且在已有文档之后才_启用_草稿功能,那么所有旧文档在重新保存之前_都不会有 _status
字段_。因此,如果你正在_向现有集合添加_版本功能,你可能需要编写访问控制函数来允许用户读取以下两种情况:
_status
等于 "published"
以及
_status
不存在
以下是一个编写访问控制函数的示例,该函数既允许访问 _status
等于 "published" 的文档,也允许访问 _status
不存在的文档:
import type { CollectionConfig } from 'payload'
export const Pages: CollectionConfig = {
slug: 'pages',
access: {
read: ({ req }) => {
// 如果有用户登录
// 允许他们检索所有文档
if (req.user) return true
// 如果没有用户
// 限制返回的文档
// 仅返回 `_status` 等于 `published`
// 或 `_status` 不存在的文档
return {
or: [
{
_status: {
equals: 'published',
},
},
{
_status: {
exists: false,
},
},
],
}
},
},
versions: {
drafts: true,
},
//.. 此处是 Pages 配置的其余部分
}
定时发布
Payload 提供了在未来定时发布/取消发布的功能,这在需要设置某些文档在未来特定日期"上线",或者反过来在特定时间后恢复为草稿状态时非常有用。
你可以通过 versions.drafts.schedulePublish: true
属性在 collections 和 globals 上启用此功能。
重要: 如果你要启用定时发布/取消发布功能, 需要确保你的 Payload 应用已配置好处理 Jobs。此功能通过在后台创建 Job 来工作, 当 job 可用时会被执行。如果你没有设置任何运行 jobs 的机制, 你的定时发布/取消发布 jobs 将永远不会被执行。
取消发布草稿
如果文档已发布,Payload 管理界面会在侧边栏顶部显示"取消发布"按钮,该按钮会将当前已发布的文档"取消发布"。可以将其视为将文档"回退"到草稿状态的一种方式。在 API 层面,这只需将文档的 _status
设置为 'draft'
即可实现。
恢复到已发布状态
如果文档已发布,并且你进行了进一步修改并保存为草稿,Payload 会在侧边栏顶部显示"恢复到已发布版本"按钮,允许你放弃草稿更改并"回退"到文档的已发布状态。你的草稿仍会被保存,但会创建一个反映文档最后发布状态的新版本。