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

发布于 2024-12-13 05:33:40 字数 1438 浏览 4 评论 0原文

我正在从事的项目使用了 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-compulated-fields

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

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

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

The project I am working on uses Plone's awesome Dexterity plugin. A couple of my custom content types have very specific names that must be computed. The way I had originally accomplished this before was by adding plone.app.content.interfaces.INameFromTitle as a behavior in the object's generic setup entry, per the manual's directions:

<?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>

Then I created an adapter that would provide 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

This method is very similar to that suggested in this blog post:

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

Unfortunately, this method stopped working after plone.app.dexterity beta and now my content items don't have their names assigned properly.

Would anyone happen to know how to extend Dexterity's INameFromTitle behavior for very specific naming use-cases?

Your help is much appreciated, thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

染火枫林 2024-12-20 05:33:40

你可以尝试以下方法。

interfaces.py

from plone.app.content.interfaces import INameFromTitle

class INameForMyType(INameFromTitle):

    def title():
        """Return a custom title"""

behaviors.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。

You could try the following.

in interfaces.py

from plone.app.content.interfaces import INameFromTitle

class INameForMyType(INameFromTitle):

    def title():
        """Return a custom title"""

in behaviors.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

I generally prefer defining my adapters using ZCML; in configure.zcml

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

but you could probably also use a grok.global_adapter.

玻璃人 2024-12-20 05:33:40

INameFromTitle 行为来做到这一点,

适应behaviors.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

我通过在 behaviors.zcmlconfigure.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" />

然后禁用 behaviors.py 中的 INameFromTitle 行为代码>profiles/types/your.contenttype.xml。

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

这不会在编辑后自动更改标题。到目前为止,我还没有像经常建议的那样成功覆盖内容类型的 klass 属性。

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

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

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

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

I did it with a behavior, by adapting to INameFromTitle

in behaviors.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

in behaviors.zcml or 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" />

Then disable INameFromTitle behavior in profiles/types/your.contenttype.xml.

Voila. This integrates very well and shows a proper title in the default view and navigation. Removing context.setTitle(title) from the adapter would just leave us with a proper id, but no title set.

This does not change the title autocratically after editing. I had, so far, no success with overriding the klass property of my content types, as often suggested.

If you define the title attribute in your schema, like:

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

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

you can easily change the title later. Hiding the title field in the addForm should be done, to avoid misunderstandings.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文