使用通用接口标记内容类型的更好方法

h2o*_*h2o 5 zope plone viewlets

我想要一个viewlet应用于同一个python egg中的几个内容类型的视图.我一直在做的是通过browser/configure.zcml应用标记接口

<configure
    xmlns="http://namespaces.zope.org/zope"
    xmlns:browser="http://namespaces.zope.org/browser"
    i18n_domain="AnnualProgramModule.content">

  <include package="plone.app.contentmenu" />

  <class class="..content.programyear.ProgramYear">
    <implements interface=".viewlets.IAnnualProgram" />
  </class>

  <class class="..content.institution.Institution">
    <implements interface=".viewlets.IAnnualProgram" />
  </class>

</configure>
Run Code Online (Sandbox Code Playgroud)

在我基于Grok的模板中,我有:

from zope.interface import Interface
from five import grok
from plone.app.layout.viewlets.interfaces import IAboveContentTitle
from AnnualProgramModule.content.interfaces import IInstitution

grok.templatedir('templates')

class IAnnualProgram(Interface):
    """Marker Interface for AnnualProgram content types
    """

class AnnualProgramViewlet(grok.Viewlet):
    grok.require('zope2.View')
    grok.viewletmanager(IAboveContentTitle)
    grok.context(IAnnualProgram)

class InstitutionViewlet(grok.Viewlet):
    grok.require('zope2.View')
    grok.context(IInstitution)
    grok.viewletmanager(IAboveContentTitle)
Run Code Online (Sandbox Code Playgroud)

这有效.但我很想知道是否有更好的方法来做到这一点.

Mar*_*ers 0

不,你正在做的实际上是解决这个问题的最佳方法。无论如何,使用标记接口是我处理问题的方法。:-)

另一种方法是您为所有不同内容类型的接口或类重新注册视图:

<browser:viewlet
    name="yourpackage.annualprogram"
    for="..content.programyear.ProgramYear"
    manager="plone.app.layout.viewlets.interfaces.IAboveContentTitle"
    template="annualprogram.pt"
    permission="zope2.View"
    />

<browser:viewlet
    name="yourpackage.annualprogram"
    for="..content.interfaces.IInstitution"
    manager="plone.app.layout.viewlets.interfaces.IAboveContentTitle"
    template="annualprogram.pt"
    permission="zope2.View"
    />
Run Code Online (Sandbox Code Playgroud)

但这要冗长得多。