跳转到主要内容

使用命名适配器动态扩展Archetypes模式。

项目描述

简介

此包允许您使用简单适配器修改 Archetypes 架构。这可以用来添加新字段、重新排序字段和字段集,或者进行其他更改。

架构扩展的最常见用途是允许附加产品增强标准 Plone 内容类型,例如添加一个可以设置以切换特殊行为的选项。

schemaextender 通过为 BaseContent 和 BaseFolder 注册 ISchema 适配器,挂载到 Archetypes 框架中,使其负责为所有从这些类派生的类型提供架构。这包括所有标准 Plone 内容类型。由于只有一个 ISchema 适配器可以激活,schemaextender 提供了使用命名适配器修改架构的自身机制。命名适配器允许为每个适配的接口注册多个 schemaextender。

有以下三种类型的适配器可用

  • ISchemaExtender:使用此适配器可以向架构添加新字段。

  • IOrderableSchemaExtender:此适配器既可以使您添加新字段,也可以重新排序字段。这比仅仅添加新字段代价更高。

  • IBrowserLayerAwareExtender:此适配器利用 plone.browserlayer,因此扩展器仅在注册了特定层时才可用。

  • ISchemaModifier:这是一个低级钩子,允许直接操作架构。这可能非常危险,如果不清楚自己在做什么,则永远不应使用!

适配器类型在 archetypes.schemaextender 的 'interfaces.py' 文件中有文档。

简单示例

例如,我们将向标准 Plone 文档类型添加一个简单的布尔字段。首先我们需要创建一个字段类

from Products.Archetypes.public import BooleanField
from archetypes.schemaextender.field import ExtensionField

class MyBooleanField(ExtensionField, BooleanField):
    """A trivial field."""

由于标准 Archetypes 字段依赖于生成访问器和修改器方法的类生成逻辑,schemaextender 不能直接使用它们。通过使用 ExtensionField 混入类,我们仍然可以使用它们。确保 ExtensionField 混入类排在第一位,以便正确覆盖标准方法。

接下来,我们需要创建一个适配器,用于添加此字段

from zope.component import adapts
from zope.interface import implements
from archetypes.schemaextender.interfaces import ISchemaExtender
from Products.Archetypes.public import BooleanWidget
from Products.ATContentTypes.interfaces import IATDocument

class PageExtender(object):
    adapts(IATDocument)
    implements(ISchemaExtender)


    fields = [
        MyBooleanField("super_power",
        widget = BooleanWidget(
            label="This page has super powers")),
            ]

    def __init__(self, context):
        self.context = context

    def getFields(self):
        return self.fields

尝试在类中存储字段,这样它们就不会在每次调用 getFields 方法时创建。通常,您应该确保 getFields 执行尽可能少的工作,因为它会被频繁调用。

最后一步是将此适配器注册到 Zope 组件架构中。由于我们已声明我们提供的接口和要适配的对象类型,因此可以在 configure.zcml 中非常快速地完成此操作(假设您将上述代码放在一个名为 extender.py 的文件中)

<configure xmlns="http://namespaces.zope.org/zope"
           xmlns:five="http://namespaces.zope.org/five">

    <include package="archetypes.schemaextender" />
    <adapter factory=".extender.PageExtender" />
</configure>

自定义字段

如果您想,也可以创建更复杂的字段类型。唯一的要求是您的字段类型需要以 ExtensionField 作为第一个父类。以下是一个在对象上切换标记接口的字段示例。

from zope.interface import Interface
from zope.interface import alsoProvides
from zope.interface import noLongerProvides
from Products.Archetypes.public import BooleanField
from archetypes.schemaextender.field import ExtensionField

def addMarkerInterface(obj, *ifaces):
    for iface in ifaces:
        if not iface.providedBy(obj):
            alsoProvides(obj, iface)


def removeMarkerInterface(obj, *ifaces):
    for iface in ifaces:
        if iface.providedBy(obj):
            noLongerProvides(obj, iface)


class ISuperPower(Interface):
    """Marker interface for classes that can do amazing things."""


class InterfaceMarkerField(ExtensionField, BooleanField):
    def get(self, instance, **kwargs):
        return ISuperPower.providedBy(instance)

    def getRaw(self, instance, **kwargs):
        return ISuperPower.providedBy(instance)

    def set(self, instance, value, **kwargs):
        if value:
            addMarkerInterface(instance, ISuperPower)
        else:
            removeMarkerInterface(instance, ISuperPower)

层感知示例

通过使用 archetypes.schemaextender.IBrowserLayerAwareExtender,扩展器仅在站点安装了特定浏览器层时才应用。

以下是一个示例 extender.py,它将新字段添加到 日期 编辑标签页上

"""

    Retrofit re-review dates to Archetypes schema.

"""

__docformat__ = "epytext"

from zope.component import adapts
from zope.interface import implements

from Products.Archetypes.public import BooleanWidget
from Products.ATContentTypes.interfaces import IATDocument
from Products.Archetypes import public as atapi
from Products.Archetypes.interfaces import IBaseContent

from archetypes.schemaextender.field import ExtensionField
from archetypes.schemaextender.interfaces import (
  ISchemaExtender, IOrderableSchemaExtender, IBrowserLayerAwareExtender)

# Your add-on browserlayer
from your.package.interfaces import IAddOnInstalled

class ExtensionDateField(ExtensionField, atapi.DateTimeField):
    """ Retrofitted date field """


class RevisitExtender(object):
    """ Include revisit date on all objects.

    An example extended which will create a new field on Dates
    tab between effective date and expiration date.
    """

    # This extender will apply to all Archetypes based content
    adapts(IBaseContent)

    # We use both orderable and browser layer aware sensitive properties
    implements(IOrderableSchemaExtender, IBrowserLayerAwareExtender)

    # Don't do schema extending unless our add-on product is installed on Plone site
    layer = IAddOnInstalled

    fields = [
        ExtensionDateField("revisitDate",
            schemata="dates",
            widget = atapi.CalendarWidget(
                label="Review Date",
                description=(u"When this date is reached, the content "
                             u"will be visible in the review task list"),
                show_hm=False,
            ),
        )
    ]

    def __init__(self, context):
        self.context = context

    def getOrder(self, schematas):
        """ Manipulate the order in which fields appear.

        @param schematas: Dictonary of schemata name -> field lists

        @return: Dictionary of reordered field lists per schemata.
        """
        schematas["dates"] = ['effectiveDate', 'revisitDate', 'expirationDate',
                              'creation_date', 'modification_date']

        return schematas

    def getFields(self):
        """
        @return: List of new fields we contribute to content.
        """
        return self.fields

注意:由于上述示例在其 implements 行中有两个接口,您的 Zope 实例启动时将会出错

TypeError: Missing 'provides' attribute

这意味着我们需要在我们的 zcml 配置中更加明确,并指定我们的适配器提供了哪两个接口之一

<adapter factory=".extender.RevisitExtender"
    provides="archetypes.schemaextender.interfaces.ISchemaExtender" />

变更日志

3.0.2 (2021-10-07)

错误修复

  • 防止在 Python 3 上安装,因为我们知道 Archetypes 在那里不能工作。[maurits] (#3330)

3.0.1 (2020-03-21)

错误修复

  • 小的打包更新。[各种] (#1)

3.0.0 (2018-10-31)

破坏性变更

  • 在PloneTestcase现在是DX后,使用AT切换到新的TestCase。没有改变功能,但需要Plone 5.2,所以我们称之为破坏性更改。[pbauer]

2.1.8 (2018-01-30)

错误修复

  • 添加Python 2/3兼容性。[maurits]

2.1.7 (2017-03-09)

错误修复

  • 更新关于Products.ATContentTypes.interfaces导入位置的文档。[thet]

  • 修复了Zope4中删除的从Globals的导入。[pbauer]

2.1.6 (2016-08-11)

修复

  • 使用zope.interface装饰器。[gforcada]

2.1.5 (2015-03-11)

  • 将测试迁移到plone.app.testing。

2.1.4 (2014-09-08)

2.1.3 (2014-02-26)

  • 修复测试 [kiorky]

2.1.2 (2013-01-13)

  • PEP8更改,文档更新。[maurits]

2.1.1 - 2011-07-04

  • 如果对象不是acquisition-wrapped,则通过本地站点钩子获取请求对象(在cachingInstanceSchemaFactory中)。这解决了使用DTML渲染的对象的缓存问题。请注意,这可能是DocumentTemplate代码中的错误。理想情况下,应该在那里解决该问题。[malthe]

2.1 - 2011-01-03

  • 使用plone.uuid查找内容UUID。[toutpt, davisagli]

  • 添加了如何使用有序扩展器和浏览器层感知扩展器的示例。[miohtama]

2.0.3 - 2010-07-07

  • 添加了回caching.zcml文件,但让它加载configure.zcml。这使得编写Plone 3/4兼容的代码更容易。[hannosch]

  • 将禁用测试期间缓存的条件提取到名为CACHE_ENABLED的全局模块变量中。[hannosch]

2.0.2 - 2010-06-13

  • 再次更改了方案缓存,以在尚未分配UID的情况下仅使用id()作为后备。id()与Acquisition包装器和ZODB级别对象的重影不稳定。我们提供了禁用缓存的显式API。[hannosch]

  • 避免在Zope 2.13下出现弃用警告。[hannosch]

  • 更改方案缓存键以避免在内容迁移期间可能存在两个具有相同UID但不同方案的对象的冲突。现在将Python id()与UID连接起来(仅id()不够好,因为具有非重叠生命周期的两个对象可能具有相同的id()值)。修复http://dev.plone.org/plone/ticket/10637。[davisagli]

2.0.1 - 2010-05-23

  • 在测试运行期间禁用方案缓存。[hannosch]

2.0 - 2010-05-23

  • 删除了caching.zcml,并默认启用缓存。您可以通过使用overrides.zcml文件来使用不同的缓存实现。[hannosch]

  • 添加了z3c.autoinclude入口点,将其标记为Plone插件。[hannosch]

1.6 - 2010-03-22

  • 修复索引访问器以支持设置自定义访问器方法。[witsch]

1.5 - 2009-11-18

  • 修复了usage.txt中的测试失败。[hannosch]

  • 标准化包元数据布局。[hannosch]

1.4 - 2009-11-05

  • 修复了方案复制以包括属性和层。[maerteijn]

1.3 - 2009-10-20

  • 重构了TranslatableExtensionField getMutator,以直接重用LinguaPlone本身生成的生成的MutatorWrapper。这避免了逻辑重复,并允许schemaextender字段使用LinguaPlone中引入的特殊引用字段处理。此更改引入了对LinguaPlone至少3.0b6的版本要求。[hannosch]

1.2 - 2009-10-10

  • 使用请求中的简单缓存添加ISchema适配器,以避免重复计算(扩展的)方案。默认情况下,适配器未启用,可以通过加载caching.zcml来激活它。[witsch]

  • 在复制原始方案时避免使用覆盖的+运算符,因为这将不必要地再次验证所有字段。[witsch]

  • 添加了缺少的更改日志条目。[hannosch, woutervh]

1.1 - 2009-06-03

  • 通过无缝使用新TranslatableExtensionField在LP安装时添加了对LinguaPlone语言无关字段的支持。[hannosch]

  • 添加了IExtensionField的正确接口。[hannosch]

  • 调整了Plone 3.3的测试。[hannosch]

  • 在文档中进行了一些小的调整:a) 不要在示例中适配类,b) 解释为什么使用命名适配器。[jensens]

  • 方案修饰符现在也具有浏览器层感知。[jessesnyder]

1.0 - 2008-07-17

  • 自1.0rc1以来没有更改。

1.0rc1 - 2008-04-07

  • 添加了可选的plone.browserlayer支持。实现IBrowserLayerAwareExtender的扩展器需要具有一个层属性。只有当指定的层处于活动状态时,这些扩展器才被考虑。[jensens]

1.0b1 - 2007-12-07

  • 实现ISchemaModifier的Schema修饰符现在负责复制它们修改的字段。请参阅README和文档字符串。[fschulze]

  • 添加了一个简单的基准测试,并通过避免大量的字段复制进行了一些优化。[fschulze, wiggy]

  • 使用标记接口而不是overrides.zcml - 这意味着您不需要在依赖产品中与overrides纠缠。[optilude]

  • 添加了代码以允许添加新的架构。我们需要一个有序字典来确保架构的顺序不会被打乱。[jensens]

  • 添加了一个小型基准测试工具。[wichert]

  • 用单元测试替换了高级测试,并扩展了测试覆盖率。[wichert]

  • 重新编写了README,使其更易于阅读。[wichert]

1.0a1 - 2007-10-15

  • 首次公开发布。

项目详情


下载文件

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

源代码发行版

archetypes.schemaextender-3.0.2.tar.gz (29.1 kB 查看散列)

上传时间

构建发行版

archetypes.schemaextender-3.0.2-py2-none-any.whl (23.8 kB 查看散列)

上传时间 Python 2

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面