有没有办法扩展Plone Dexterity的INameFromTitle行为?

时间:2011-11-01 23:48:58

标签: plone adapter behavior dexterity

我正在开发的项目使用了Plone令人敬畏的Dexterity插件。我的一些自定义内容类型具有必须计算的非常具体的名称。我之前完成此操作的方式是根据手册的说明,在对象的通用设置条目中添加 plone.app.content.interfaces.INameFromTitle 作为行为:

<?xml version="1.0"?>
<object name="avrc.aeh.cycle" meta_type="Dexterity FTI">
  ...
  <property name="schema">myproject.mytype.IMyType</property> 
  <property name="klass">plone.dexterity.content.Item</property>
  ...
  <property name="behaviors">
    <element value="plone.app.content.interfaces.INameFromTitle" />
  </property>
  ...
</object>

然后我创建了一个提供INameFromTitle的适配器:

from five import grok
from zope.interface import Interface
import zope.schema
from plone.app.content.interfaces import INameFromTitle

class IMyType(Interface):

    foo = zope.schema.TextLine(
        title=u'Foo'
        )

class NameForMyType(grok.Adapter):
    grok.context(IMyType)
    grok.provides(INameFromTitle)

    @property
    def title(self):
        return u'Custom Title %s' % self.context.foo

此方法与本博文中的建议非常相似:

http://davidjb.com/blog/2010/04/plone-and-dexterity-working-with-computed-fields

不幸的是,此方法在plone.app.dexterity测试版之后停止工作,现在我的内容项目的名称没有正确分配。

是否有人碰巧知道如何针对非常具体的命名用例扩展Dexterity的INameFromTitle行为?

非常感谢您的帮助,谢谢!

2 个答案:

答案 0 :(得分:4)

您可以尝试以下操作。

interfaces.py

中的

from plone.app.content.interfaces import INameFromTitle

class INameForMyType(INameFromTitle):

    def title():
        """Return a custom title"""
acts.py

中的

from myproject.mytype.interfaces import INameForMyType

class NameForMyType(object):
    implements(INameForMyType)

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

    @property
    def title(self):
        return u"Custom Title %s" % self.context.foo

我通常更喜欢使用ZCML定义我的适配器;在 configure.zcml

<adapter for="myproject.mytype.IMyType"
         factory=".behaviors.NameForMyType"
         provides=".behaviors.INameForMyType"
         />

但您也可以使用grok.global_adapter。

答案 1 :(得分:3)

我通过适应INameFromTitle

来做一个行为 acts.py

中的

class INameFromBrandAndModel(Interface):
    """ Interface to adapt to INameFromTitle """

class NameFromBrandAndModel(object):
    """ Adapter to INameFromTitle """
    implements(INameFromTitle)
    adapts(INameFromBrandAndModel)

    def __init__(self, context):
        pass

    def __new__(cls, context):
        brand = context.brand
        model = context.modeltype    
        title = u'%s %s' % (brand,model)
        inst = super(NameFromBrandAndModel, cls).__new__(cls)

        inst.title = title
        context.setTitle(title)

        return inst
的行为.zcml configure.zcml

<plone:behavior

    title="Name from brand and model"
    description="generates a name from brand and model attributes"
    for="plone.dexterity.interfaces.IDexterityContent"
    provides=".behavios.INameFromBrandAndModel"
    />

<adapter factory=".behaviors.NameFromBrandAndModel" />

然后在profiles/types/your.contenttype.xml中禁用INameFromTitle行为。

       

瞧。这种集成非常好,并在默认视图和导航中显示正确的标题。从适配器中删除context.setTitle(title)只会给我们留下正确的ID,但不会设置标题。

编辑后,这不会以标准方式更改标题。到目前为止,我没有像通常建议的那样覆盖我的内容类型的klass属性。

如果在架构中定义title属性,例如:

class IBike(form.Schema):
    """A bike
    """

    title = schema.TextLine(
        title = _(u'Title'),
        required = False,
    )

您可以稍后轻松更改标题。应该在addForm中隐藏title字段,以避免误解。