我一直在使用架构行为没有问题,但我想要一个提供一些逻辑的方法。现在我有
class IMyFoo(form.Schema):
requester = schema.TextLine(title=_(u"Requestor"),
required=False,
)
def foo(self):
""" foo """
alsoProvides(IMyFoo, IFormFieldProvider)
在zcml中
<plone:behavior
title="My behavior"
description="Some desc"
provides=".behaviors.IMyFoo"
for=".interfaces.ISomeInterface"
/>
我在portal_types中的内容类型的行为部分中包含了IMyFoo。这给了我架构但不是foo()方法。所以我尝试使用以下代码
阅读http://plone-training.readthedocs.org/en/latest/behaviors2.html来为它添加工厂class MyFoo(object):
def foo(self):
return 'bar'
在zcml中
<plone:behavior
title="My behavior"
description="Some desc"
provides=".behaviors.IMyFoo"
factory=".behaviors.MyFoo"
for=".interfaces.ISomeInterface"
/>
但这似乎没有什么区别,或者至少,我不知道如何访问该方法。我能够得到的最接近的是:
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" />
我将IMyFoo放在fti中的behavior属性中,然后通过遍历所有行为来调用它,例如
behavior = resolveDottedName(context.portal_types.getTypeInfo(context.portal_type).behaviors[-1]))
behavior(self).myfoo()
当然,通过这样的FTI并不是正确的方法。但是我现在处于亏损状态。在Archetypes中,我只需创建一个mixin类,并使用我想要使用的任何内容类型继承它。我可以在这里做同样的事,但我的理解是行为应该是它们的替代品,所以我想弄清楚如何使用这种首选方法。
答案 0 :(得分: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'
然后您的唯一zcml声明将是:
<plone:behavior
title="My behavior name"
description="Behavior description"
provides=".behavior.IMyFoo"
factory=".behavior.MyFoo"
for="plone.dexterity.interfaces.IDexterityContent"
/>
而且,您可以使用以下代码来实现您的方法:
IMyFoo(myFooishObject).foo()
注意使用IDexterityContent。您正在创建可应用于任何敏捷内容的行为。因此,行为适配器应该是 这个非常通用的接口。