Есть ли способ расширить поведение INameFromTitle Plone Dexterity? - PullRequest
7 голосов
/ 02 ноября 2011

В проекте, над которым я работаю, используется удивительный плагин Ловкости Plone.У пары моих пользовательских типов контента есть очень конкретные имена, которые должны быть вычислены.Первоначально я достиг этого ранее, добавив 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 ]

4 голосов
/ 05 января 2012

Вы можете попробовать следующее.

in interfaces.py

from plone.app.content.interfaces import INameFromTitle

class INameForMyType(INameFromTitle):

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

в поведениеiors.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.

3 голосов
/ 13 октября 2012

Я сделал это с помощью поведения, адаптировав его к INameFromTitle

в moodiors.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

в moodiors.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" />

Затем отключите поведение INameFromTitle в profiles/types/your.contenttype.xml.

Вуаля.Это очень хорошо интегрируется и показывает правильный заголовок в представлении и навигации по умолчанию.При удалении context.setTitle(title) из адаптера у нас останется только правильный идентификатор, но заголовок не будет установлен.

Это не изменит заголовок автоматически после редактирования.До сих пор мне не удалось переопределить свойство klass моих типов контента, как это часто предлагалось.

Если вы определяете атрибут title в своей схеме, например:

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

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

Вы можете легко изменить заголовок позже.Во избежание недоразумений необходимо скрыть поле заголовка в addForm.

...