【问题标题】:Plone 4 : How to customize a method in Archetypes content types?Plone 4:如何在 Archetypes 内容类型中自定义方法?
【发布时间】:2015-03-13 23:56:29
【问题描述】:

我尝试在 Plone 4.3.3 下,在我的一个产品中自定义原型内容类型的类方法。

我有一个产品bsw.produit_1,其内容类型为MyContent,定义如下:

class MyContent(base.ATCTContent):

    implements(IMyContent)

    meta_type = "MyContent"
    schema = MyContent`

    def ma_fonction(self):

        ......
        return res

我想在另一个产品中修改我的函数ma_fonction 的代码。我曾尝试使用适配器并遵循 plone 文档,但没有成功。

我希望自定义功能的类:

class CustomClass(object):
    """  """

    implements(IMyContent)
    adapts(IMyContent)

    def at_post_payment_script(self, obj_transaction):
        """ """

            ......
            # My new code
            return res

我声明适配器的configure.zcml

  <adapter for="bsw.produit_1.content.mycontent.MyContent"
           provides="bsw.produit_1.interfaces.IMyContent"
           factory=".customclass.CustomClass" />

在我的 zcml 声明中,我还尝试将 archetypes.schemaextender.interfaces.ISchemaExtender 设置为 provides 或将接口 IMyContent 设置为 for 而不是类。

这些都不起作用,每次都不会执行自定义代码。有人对此有解决方案吗?

【问题讨论】:

  • 我已尽我所能翻译成英文,我想这是您的问题被标记为“不清楚您在问什么”的原因之一。随意改进我的翻译,我希望我正确地表达了你的意图。
  • 当您说“我希望自定义函数的类:...”时,我不明白您的意思。您的范围不是简单地覆盖原始方法MyContent.ma_fonction 吗?
  • @keul:原来是“定制器”,我可能应该将其渲染为“更改”。我不确定为什么 sn-ps 中有两个不同的方法名称,不过,也许 Sebastien 可以帮助我们。
  • @keul:ma_fonction 是一种原型方法,在 plone 文档中它说使用适配器来覆盖原型方法。你知道另一种覆盖原型方法的方法吗?
  • @Sebastien 我认为您误解了文档中的某些内容。

标签: adapter plone archetypes plone-4.x


【解决方案1】:

您需要的解决方案取决于您想要实现的目标。

但archetypes.schemaextender 是错误的解决方案。 schemaextender 用于修改架构,包括:

  • 字段顺序
  • 字段/小部件属性
  • 架构
  • 字段的设置器/获取器
  • 新字段
  • 覆盖字段

实现自己的适配器绝对是正确的方法。

首先,您需要为默认行为实现一个适配器。 其次,您需要调整上下文和请求。该请求很重要,因为如果您的other 产品已安装,这是一种定义更具体的适配器的方法。

默认实现的 Python 代码 (adapter.py):

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


class IBehavior(Interface):
    def __init__(context, request)
        """Adapts context and request"""

    # ... more ...


class DefaultBehavior(object):
    implements(IBehavior)
    adapts(IMyContent, Interface)  # IMPORTAN two discriminators 

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

    def __call__(self):

        # your default implementation goes here.

用zcml注册适配器:

<adapter factory=".adapter.DefaultBehavior" />

您现在可以调用ma_fonction 中的默认适配器

from zope.component import getMultiAdapter


class MyContent(base.ATCTContent)

    def ma_fonction(self):
        adapter = getMultiAdapter((self, self.REQUEST), IDefaultBehavior)
        return adapter()

现在您可以使用浏览器层在您的other 产品中实现更具体的适配器。检查文档,how to register a browserlayer

在您的otherpackage 中,您现在可以注册一个适配器,该适配器实现相同的IBehavior 接口,但也适应您的浏览器层。

from other.package.interfaces import IOtherPackageLayer
from zope.component import adapts
from zope.interface import implements


class DifferenBehavior(object):
    implements(IBehavior)
    adapts(IMyContent, IOtherPackageLayer)  # IMPORTAN adapt the browserlayer not Interface 

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

    def __call__(self):

        # your different implementation goes here.

也用 zcml 注册:

<adapter factory=".adapter.DifferenBehavior" />

如果未安装 other 软件包,您的 ma_fonction 现在会调用默认适配器。如果安装了other 包,则使用不同的适配器。

【讨论】:

    【解决方案2】:

    您可以使用的最简单的方法(虽然在政治上不正确!)是猴子补丁

    看看collective.monkeypatcher,您只需要这样的配置(在您的第 3 方产品中):

    <monkey:patch
        description=""
        class="your.package.MyContent"
        original="ma_fonction"
        replacement=".monkeys.new_ma_fonction"
        />
    

    然后在您的包中创建一个 monkeys.py 模块,其中包含新方法:

    def new_ma_fonction(self):
        # do stuff
        return res
    

    【讨论】:

    • 我也尝试使用collective.monkeypatcher,但我的自定义代码适用于我实例上的每个克隆站点。我只想在我的产品已安装时应用我的自定义代码
    • 所以你可以这样做:你的产品可以注册一个 Plone 浏览器层 (docs.plone.org/develop/plone/views/…) 并且在 new_ma_fonction 中你可以检查当前请求是否提供了接口: if MyBrowserLayerInterface.providedBy(self .REQUEST): ...
    猜你喜欢
    • 1970-01-01
    • 2017-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多