跳转到主要内容

草稿内容的低级容器

项目描述

介绍

Travis CI badge Coveralls badge

plone.app.drafts实现了在Plone中管理自动保存的内容草稿的服务。这解决了两个问题

  • 如果在编辑页面时浏览器意外关闭或崩溃,所有更改都将丢失。

  • 某些数据可能需要异步管理,例如通过视觉编辑器的弹出对话框。这些数据应在表单保存后(在添加表单的情况下,这是不可能的)才保存。

前者问题涉及任何内容添加或编辑表单。后者特别适用于由plone.app.tiles及其依赖项实现的“瓷砖”模型。

安装

您可以通过在您的setup.py中依赖它或将其添加到您的构建配置中的eggs列表中来正常安装plone.app.drafts。该软件包将自动为Plone进行配置;无需添加ZCML缩略语。

您还需要从门户快速安装工具或Plone的附加组件控制面板中安装产品。

草稿存储

安装后,您应该会在ZMI中注意到一个名为portal_drafts的新工具。当草稿被创建时,您可以在这里浏览它们,并在认为它们已过时的情况下清除它们。

要在代码中访问草稿存储,请将其作为(本地)实用工具查找

>>> from zope.component import getUtility
>>> draftStorage = getUtility(IDraftStorage)

草稿存储包含创建、查找和丢弃草稿的方法。这对于集成逻辑非常有用。

通过使用键的层次结构来访问草稿,所有键都是字符串

  1. 拥有草稿的用户ID

  2. 一个唯一的“目标对象”键,代表正在草拟的对象

  3. 一个唯一的草稿名称

目标对象键是惯例的字符串表示形式,是唯一整数ID(通过zope.intid),对于表示正在编辑的现有内容对象的草稿,或如

'<container-intid>:<portal_type>'

(例如,'123456:Document')对于表示要添加到特定容器的对象的草稿。

草稿名称是唯一的,并在创建草稿时分配。

有关如何根据这些键访问草稿的详细信息,请参阅IDraftStorage接口。

草稿对象本身是一个提供IDraft接口的最小持久对象。重要的是,它不是一个完整的内容对象。它没有内在的安全性,没有工作流,没有标准字段。然而,它是可注解的,即它可以适配到IAnnotations

草稿有一些基本属性(__name___draftUserId_draftTargetKey),但其他方面都是空白画布。草稿数据可以存储为属性或注释。所使用的属性取决于如何集成草稿。两种主要模式是

自动保存

显式或定时背景请求会将编辑表单提交给处理器,处理器会提取表单数据并将其保存到草稿对象中,例如在一个

字典中。草稿会定期更新。在成功保存或取消草稿时,草稿会被简单丢弃。但是,如果用户在浏览器崩溃或会话被放弃后返回编辑屏幕,请求可以通过在渲染编辑表单之前将草稿数据复制到真实的request.form字典中来恢复。如果编辑表单表现良好,它应该显示最后自动保存的值。然后可以编辑这些值,在正常保存之前。

异步更新

可以使用AJAX对话框异步配置对象。例如,支持附件的内容类型可能使用此类对话框上传附件文件。这些文件需要临时存储,但在底层的编辑表单保存之前不应与实际内容对象持久化(如果被取消,则应丢弃)。文件上传处理器可以将数据保存到草稿存储,然后在保存时将其复制到最终位置。

plone.app.drafts.utils模块中提供了一个名为syncDraft的辅助函数,用于此目的。它会查找任何数量的名为IDraftSyncer的多适配器(在草稿对象和目标内容对象上),并依次调用它们。

当前草稿管理

要从代码中访问当前草稿,请使用getCurrentDraft()辅助函数,并传入当前请求

>>> from plone.app.drafts.utils import getCurrentDraft
>>> currentDraft = getCurrentDraft(request)

如果当前没有草稿,它可能返回None。可能存在创建草稿所需的信息(用户ID和目标键),但尚未创建草稿。在这种情况下,您可以通过传递create=True来请求按需创建新草稿。

当前草稿的用户ID、目标键和(一旦草稿已创建)草稿名称将通过将其适配到接口ICurrentDraftManagement从请求中查找。您通常不需要自己使用此接口,除非您正在将草稿存储与外部框架集成。

默认的ICurrentDraftManagement适配器允许显式设置用户ID、目标键和草稿名称。如果没有设置,它们将从请求中读取。这意味着它们可能来自请求参数或cookie。请求键为plone.app.drafts.targetKeyplone.app.drafts.draftName。用户ID始终默认为当前登录用户的ID。

ICurrentDraftManagement适配器还公开了生命周期函数,可以保存或丢弃当前草稿信息。默认实现使用为编辑页面对应的路径设置的cookie来完成此操作。确保此cookie为特定路径设置的责任在于添加/编辑表单集成代码,以确保此cookie为特定路径设置,以防止“泄露”到其他编辑页面,但仍允许AJAX对话框和其他异步请求在需要时获取草稿信息。

集成

archetypes模块中提供了Archetypes集成,如果已安装Archetypes,则进行配置。集成的工作方式如下

  • 当用户进入添加/编辑表单时,Archetypes 会触发一个 IEditBegunEvent 事件。为此事件安装的事件处理器将计算上下文的目标键,考虑到基于 portal_factory 工具的“添加表单”。如果可以计算出键,它将通过以下方式通过 ICurrentDraftManagement 适配器保存。草稿不会立即创建,但如果在存储中找到该用户 id 和键的单个草稿,则将草稿名称保存起来,以便在调用 getCurrentDraft() 时返回。同时还会计算出 cookie 路径并保存。这确保了如果草稿是在具有“更深” URL 的异步请求中创建的,cookie 路径将保持相同。

  • IObjectInitializedEventIObjectEditedEvent 安装了事件处理器,这两个事件分别在用户点击有效的添加或编辑表单上的“保存”按钮时触发。此处理器将获取在编辑周期中创建的当前草稿,并使用 syncDraft() 方法根据需要进行同步。然后丢弃草稿以及当前草稿信息,导致 cookie 过期。

  • 还安装了 IEditCancelledEvent 的事件处理器,该事件在用户点击“取消”时触发。这简单地将草稿和当前草稿信息丢弃,而不进行同步。

草稿代理

简单的草稿集成通常会直接在草稿对象上存储数据。然而,有时有一个对象作为“真实”对象的门面来操作可能很有用,以便

  • 如果读取从未设置在草稿上的属性或注释值,则使用底层目标对象的值。

  • 如果设置属性或注释值,则将其写入草稿。如果随后读取它,则从草稿中读取。

  • 如果删除属性或注释值,则从草稿中删除,并记录已删除的事实,以便在草稿“保存”时(例如通过 IDraftSyncer 适配器)稍后与底层对象同步。

要获得这些语义,可以创建一个如下所示的 DraftProxy 对象

>>> from plone.app.drafts.proxy import DraftProxy
>>> proxy = DraftProxy(draft, target)

在这里,draft 是一个 IDraft 对象,而 target 是其草稿的对象。如果删除了属性,它们将存储在两个集合中的一个

>>> deletedAttributes = getattr(draft, '_proxyDeleted', set())
>>> deletedAnnotations = getattr(draft, '_proxyAnnotationsDeleted', set())

请注意,如果从未删除任何内容,则这些属性可能不存在,因此我们需要进行防御性检索。

变更日志

2.0.0 (2022-07-22)

  • 移除 Archetypes。此版本针对 Plone 5.2+ 以及 Python 3.6+。

  • 修复类安全警告 [petschki]

1.1.3 (2019-02-10)

  • Python 3 兼容 [vangheem, petschki]

1.1.2 (2017-07-03)

  • 修复草稿同步失败的问题,因为草稿可能没有 aq 包装 [datakurre]

1.1.1 (2016-09-09)

  • 移除遗忘的调试打印 [datakurre]

1.1.0 (2016-09-09)

  • 添加对 IDisplayFormDrafting 标记的请求时 Dexterity 内容草稿预览的支持 [datakurre]

  • 修复了重复设置未设置 cookie 值的问题 [vangheem]

  • 修复了在调用对象修改事件订阅者(尤其是索引)之前始终同步草稿的问题 [datakurre]

  • 添加行为短名 plone.draftable。 [jensens, datakurre]

  • 更新测试基础设施并修复代码分析错误。 [gforcada]

1.0 (2016-03-28)

  • 确保在初始化草稿代理对象之前草稿可用 [vangheem]

1.0b3 (2015-06-10)

  • 修复了草稿导致“AttributeError:此对象没有 id”的问题 [datakurre]

  • 修复了具有不同内容类型但上下文具有冲突草稿的添加表单的问题 [datakurre]

1.0b2 (2015-06-02)

  • 修复了Dexterity草稿中出现错误的portal_type的罕见问题 [datakurre]

1.0b1 (2015-05-26)

  • 当内容类型的草稿行为启用时,支持在Dexterity的添加和编辑表单上草稿 [datakurre]

  • 当内容类型的草稿行为启用时,支持在Dexterity的添加和编辑表单上自动保存(使用AJAX验证调用) [datakurre]

  • 改为使用UUID而不是intids [datakurre]

  • 将Archetypes支持默认设置为禁用 [datakurre]

    可以通过zcml包含Archetypes支持

    <include package="plone.app.drafts" file="archetypes.zcml" />

1.0a2 (2011-10-11)

  • 添加MANIFEST.in以修复我们之前的发布。历史文件缺失。

1.0a1 (2011-10-10)

  • 首次发布。

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分布

plone.app.drafts-2.0.0.tar.gz (36.1 kB 查看散列)

上传时间

构建分布

plone.app.drafts-2.0.0-py3-none-any.whl (31.6 kB 查看散列)

上传时间 Python 3

支持者