plone:portlet vs plone:portletRenderer(子类化问题)

时间:2011-08-02 19:32:32

标签: plone portlet

将网站从Plone 3升级到Plone 4时,我们遇到了一个奇怪的错误:

我们定义了许多自定义portlet。其中一个是“Jobs”portlet,它是一个轻微定制的News Portlet。这是来自新闻portlet的子类,如下所示:

http://plone.org/documentation/manual/developer-manual/portlets/appendix-practicals/subclassing-new-portlets

那是:

<plone:portlet
  name="falcon.JobsPortlet"
  interface=".portlets.IFalconJobsPortlet"
   ...
  renderer=".portlets.FalconJobsRenderer"
 />

其中IFalconJobsPortlet来自INewsPortlet的子类:

from plone.app.portlets.portlets.news import INewsPortlet

class IFalconJobsPortlet(INewsPortlet):
 """Interface for Jobs portlet uses the same schema as News Portlet"""

我们也(单独)想要替换标准INewsPortlet中的render类 为了提供自定义模板:

<plone:portletRenderer
   portlet="plone.app.portlets.portlets.news.INewsPortlet"
   class=".portlets.FalconNewsRenderer"
   layer=".interfaces.IThemeSpecific"
   />

这在Plone 3中运行良好。这可能只是一气呵成,或者它 可能是<plone:portletRenderer>之前运行过的情况 <plone:portlet>,现在运行。

在Plone 4中,falcon.JobsPortlet设置正确,但随后<plone:portletRenderer> 启动并替换renderer子句,以便

".portlets.FalconJobsRenderer" (correct)     is replaced with
".portlets.FalconNewsRenderer" (incorrect)

这种情况下的解决方案/解决方法很简单:我停止了子类化 INewsPortlet,只是手动从原始超类复制模式:

class IFalconJobsPortlet(IPortletDataProvider):
  """Interface for Jobs portlet uses the same schema as News Portlet"""
 count = ...
 state = ...

我的问题,供将来参考:

有没有办法安全地合并<plone:portlet>和 当子类化的portlet正在运行时<plone:portletRenderer>

1 个答案:

答案 0 :(得分:0)

如果您未在layer="..."注册中使用<plone:portlet name="falcon.JobsPortlet"...>,则可能是根。 ZCML用于注册适配器的ZCA基于接口特异性提供一个查找优先级。所以我猜你自己在<plone:portletRenderer>而不是<plone:portlet>中提供了一个图层,然后<plone:portletRenderer>中的渲染器与两者的portlet接口匹配,并且图层更具体,因此它赢了。

由于只有<plone:portletRenderer>支持图层规范,我只需为FalconJobsRenderer添加<plone:portletRenderer>注册,该注册为同一层注册,并确保正确的优先级。这样您就可以恢复您的变通方法和子类INewsPortlet。子类化INewsPortlet更合适。