2015-01-30 2 views
2

Я использую поведение схемы без проблем, но также хочу иметь метод, который обеспечивает некоторую логику. Сейчас у меня естьИспользование поведения ловкости для предоставления метода

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" 
    /> 

Я включил IMyFoo в разделе поведения типа контента в portal_types. Это дает мне схему, но не метод 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 в поведении атрибутов в ФТИ, а затем вызвать его, пройдя через все поведений с чем-то вроде

behavior = resolveDottedName(context.portal_types.getTypeInfo(context.portal_type).behaviors[-1])) 
behavior(self).myfoo() 

Конечно, пройти через FTI, как это, это не правильный способ сделать это. Но сейчас я в растерянности. В Archetypes я бы просто сделал класс mixin и наследовал его с любым типом контента, который я хотел использовать. Я мог бы сделать то же самое здесь, но я понимаю, что поведение должно быть заменой для них, поэтому я хотел бы выяснить, как использовать этот предпочтительный метод.

+0

Возможно, мне нужно просто просматривать браузер? Мне не нужно ничего делать с объектом запроса, так что это выглядит немного глупо, но это сработает. – Esoth

ответ

6

Как вы обнаружили, класс схемы действительно является просто интерфейсом. Он не может предоставить какие-либо методы. Чтобы обеспечить больше функциональности, вам необходимо подключить свой интерфейс поведения к заводскому классу, который адаптирует объект ловкости для обеспечения вашего интерфейса.

Так что, если ваш behaviors.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. Вы создаете поведение, которое может быть применено к любому содержимому Ловкости. Таким образом, адаптер для работы должен быть для, что очень общий интерфейс.

+0

Спасибо Стив. Это все еще требует, чтобы я знал, что хочу использовать интерфейс IMyFoo. Если я хочу найти все варианты поведения, которые предоставляют метод foo, мне придется перебирать список поведения, определенного в fti? – Esoth

+0

И что, если какое-то поведение имеет метод foo, который сделал что-то, чего вы не хотели? Вся цель архитектуры компонента заключается в том, чтобы изолировать аспекты объекта. Последний арендатор Дзэн Питона: «Пространства имен - одна хорошая идея - давайте сделаем больше!» – SteveM

+0

Похоже, вы сразу после адаптера или адаптеров. У вас может быть адаптер, определенный для «*», а затем переопределить его для более конкретных интерфейсов. – SteveM

Смежные вопросы