使用灵巧行为来提供方法

Eso*_*oth 2 zope plone grok dexterity

我一直在使用模式行为没有问题,但我想要一个提供一些逻辑的方法.现在我有

class IMyFoo(form.Schema):
    requester = schema.TextLine(title=_(u"Requestor"),
              required=False,
          )

    def foo(self):
      """ foo """

alsoProvides(IMyFoo, IFormFieldProvider)
Run Code Online (Sandbox Code Playgroud)

并在zcml中

<plone:behavior
    title="My behavior"
    description="Some desc"
    provides=".behaviors.IMyFoo"
    for=".interfaces.ISomeInterface"
    />
Run Code Online (Sandbox Code Playgroud)

我在portal_types中的内容类型的行为部分中包含了IMyFoo.这给了我架构但不是foo()方法.所以我尝试使用以下代码阅读http://plone-training.readthedocs.org/en/latest/behaviors2.html来为它添加工厂

class MyFoo(object):    
    def foo(self):
      return 'bar'
Run Code Online (Sandbox Code Playgroud)

并在zcml中

<plone:behavior
    title="My behavior"
    description="Some desc"
    provides=".behaviors.IMyFoo"
    factory=".behaviors.MyFoo"
    for=".interfaces.ISomeInterface"
    />
Run Code Online (Sandbox Code Playgroud)

但这似乎没有什么区别,或者至少,我不知道如何访问该方法.我能够得到的最接近的是:

class IMyFoo(Interface):
  """ Marker """

class MyFoo(object):

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

  def foo(self):
    return 'bar'

<adapter for=".interfaces.ISomeInterface"
     factory=".behaviors.MyFoo"
     provides=".behaviors.IMyFoo" />
Run Code Online (Sandbox Code Playgroud)

我将IMyFoo放在fti中的behavior属性中,然后通过遍历所有行为来调用它

behavior = resolveDottedName(context.portal_types.getTypeInfo(context.portal_type).behaviors[-1]))
behavior(self).myfoo()
Run Code Online (Sandbox Code Playgroud)

当然,通过这样的FTI并不是正确的方法.但是我现在处于亏损状态.在Archetypes中,我只需创建一个mixin类,并使用我想要使用的任何内容类型继承它.我可以在这里做同样的事,但我的理解是行为应该是它们的替代品,所以我想弄清楚如何使用这种首选方法.

Ste*_*veM 6

正如您所发现的,架构类实际上只是一个接口.它无法提供任何方法.要提供更多功能,您需要将行为接口连接到工厂类,该工厂类调整灵活性对象以提供接口.

所以,如果您的behavior.py看起来像这样:

# your imports plus:
from plone.dexterity.interfaces import IDexterityContent
from zope.component import adapts
from zope.interface import implements

class IMyFoo(form.Schema):
    requester = schema.TextLine(
      title=_(u"Requestor"),
      required=False,
      )

    def foo(self):
      """ foo """

alsoProvides(IMyFoo, IFormFieldProvider)

class MyFoo(object):    
    implements(IMyFoo)
    adapts(IDexterityContent)

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

    def foo(self):
      return 'bar'
Run Code Online (Sandbox Code Playgroud)

然后你的唯一zcml声明将是:

<plone:behavior
    title="My behavior name"
    description="Behavior description"
    provides=".behavior.IMyFoo"
    factory=".behavior.MyFoo"
    for="plone.dexterity.interfaces.IDexterityContent"
    />
Run Code Online (Sandbox Code Playgroud)

并且,您将使用以下代码来实现您的方法:

IMyFoo(myFooishObject).foo()
Run Code Online (Sandbox Code Playgroud)

注意使用IDexterityContent.您正在创建可应用于任何敏捷内容的行为.因此,行为适配器应该用于非常通用的接口.