我正在开发的项目使用了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行为?
非常感谢您的帮助,谢谢!
答案 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字段,以避免误解。