adapter - Plone 人 4 : How to customize a method in Archetypes content types?

标签 adapter plone archetypes plone-4.x

我尝试在 Plone 4.3.3 下在我的产品之一中自定义原型(prototype)内容类型的类方法。

我有一个产品 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 或将接口(interface) IMyContent for 而不是类。

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

最佳答案

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

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

  • 字段顺序
  • 字段/小部件属性
  • 架构
  • 字段的 setter/getter
  • 新字段
  • 覆盖字段

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

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

默认实现的 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()

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

在您的other包中,您现在可以注册一个适配器,它实现相同的IBehavior接口(interface),但也适应您的浏览器层。

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 软件包,则使用不同的适配器。

关于adapter - Plone 人 4 : How to customize a method in Archetypes content types?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29011248/

相关文章:

android - RecyclerView 布局发生变化,滚动时值被截断

具有不同接口(interface)的 C++ 适配器,其中接口(interface)可能具有不同类型/数量的输入参数

plone - 有没有办法做一个保留层次结构的portal_catalog?

java - Eclipse (STS) 试图创建 appfuse-basic-jsf :RELEASE fails

ant - Maven 原型(prototype)的替代方案

maven - 用maven创建java资源webapp文件夹结构

android - 在 onItemClickListener 中获取 subview

Android:按下 ListView 项目中的按钮

plone - 我可以在 Dexterity 中创建表格数据字段吗?

Plone 中用户内容的图像和媒体库