2015-01-30 14 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" 
    /> 

에 나는 portal_types에서 콘텐츠 형식의 행동 섹션에 IMyFoo 포함되어 있습니다. 이것은 나에게 스키마를 제공하지만 foo() 메소드는 제공하지 않는다. 그래서 나는 다음과 같은 코드

class MyFoo(object):  
    def foo(self): 
     return 'bar' 

http://plone-training.readthedocs.org/en/latest/behaviors2.html을 읽고 그리고 zcml

<plone:behavior 
    title="My behavior" 
    description="Some desc" 
    provides=".behaviors.IMyFoo" 
    factory=".behaviors.MyFoo" 
    for=".interfaces.ISomeInterface" 
    /> 

에 대한 공장을 추가하려고하지만이 차이를 만들 것, 또는 적어도하지 않았다, I 그 방법에 접근하는 방법을 모른다. 내가 올 수 있었던 가장 가까운 않습니다 :

내가 행동에 IMyFoo을 넣어
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" /> 

이 FTI에 속성을 다음

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

같은 것을 모든 행동을 통해 도보로 호출 확실히 그런 FTI를 통해가는 것은 적절한 방법이 아닙니다. 그러나 나는이 시점에서 실패하고있다. Archetypes에서는 믹스 인 클래스를 만들고 그것을 사용하고 싶은 컨텐트 타입을 상속받습니다. 나는 여기서도 똑같이 할 수는 있지만, 행동은 그것들을 대신 할 행동이라고 생각한다. 그래서 나는이 바람직한 방법을 사용하는 방법을 알아 내고 싶다.

+0

아마 브라우저보기 만 사용해야합니까? 요청 개체를 사용하여 아무 것도 할 필요가 없으므로 약간 어리석은 것처럼 보일 수 있지만 작동 할 것입니다. – Esoth

답변

6

발견했듯이 스키마 클래스는 실제로 인터페이스 일뿐입니다. 어떤 방법도 제공 할 수 없습니다. 더 많은 기능을 제공하려면 비헤이비어 객체를 사용하여 인터페이스를 제공하는 팩토리 클래스에 비헤이비어 인터페이스를 연결해야합니다.

그래서, 당신의 behaviors.py이 보이는 경우 : 당신이 코드를 사용하여 방법을 도달 할 것이다

<plone:behavior 
    title="My behavior name" 
    description="Behavior description" 
    provides=".behavior.IMyFoo" 
    factory=".behavior.MyFoo" 
    for="plone.dexterity.interfaces.IDexterityContent" 
    /> 

을 그리고 :

# 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' 

그런 다음 1과 유일한 zcml 선언 될 것이다 like :

IMyFoo(myFooishObject).foo() 

IDexterityContent의 사용에 유의하십시오. 모든 민첩성 콘텐츠에 적용될 수있는 동작을 만들고 있습니다. 따라서 동작 어댑터는 매우 일반적인 인터페이스 인의 경우 이어야합니다.

+0

스티브에게 감사드립니다. 그래도 IMyFoo 인터페이스를 사용하고 싶다는 것을 알고 있어야합니다. foo 메서드를 제공하는 모든 동작을 찾으려면 fti에 정의 된 동작 목록을 반복해야합니까? – Esoth

+0

그리고 어떤 행동에 원치 않는 것을 한 foo 방법이 있다면 어떨까요? 구성 요소 아키텍처의 요점은 객체의 측면을 격리하는 것입니다. Zen of Python의 마지막 거주자 : "네임 스페이스는 훌륭한 아이디어를 고수하는 것입니다. 더 많은 것을 해보십시오!" – SteveM

+0

어댑터 나 어댑터 바로 뒤에있는 것처럼 들립니다. "*"에 대해 어댑터를 정의한 다음 더 구체적인 인터페이스를 위해 어댑터를 대체 할 수 있습니다. – SteveM