开发者

How to override Plone's display menu for special case content?

To get a one-off view on a Plone folder I do something like this (not all code shown):

In configure.zcml:

<!-- Marker interface. Set this on the folder through the ZMI
     interfaces tab.
  -->
<interface interface=".interfaces.IMySpecialFolder" />

In browser/configure.zcml:

<!-- Special case view. Set as the folder's view through the ZMI
     properties tab (layout property).
  -->
<browser开发者_StackOverflow:page
  for="..interfaces.IMySpecialFolder"
  name="special"
  template="special.pt"
  permission="zope2.View"
  />

This works great, but I would like to control the folder's display menu to list only my special case view. I can add it, and it shows up only on my marked folder, but I have to change the site-wide ATFolder FTI.

In browser/configure.zcml:

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

<browser:menuItem
  for="..interfaces.IMySpecialFolder"
  menu="plone_displayviews"
  title="Special view"
  action="@@special"
  description="Special case folder view"
  />

In profiles/default/types/Folder.xml:

<?xml version="1.0"?>
<object name="Folder">
 <property name="view_methods" purge="False">
  <element value="special"/>
 </property>
</object>

Of course I cannot remove the existing available view methods without affecting every folder on the site.

Is there a way to do this one-off display menu tweaking without changing a content type's FTI?

Actually, it seems like this problem has been tackled before. p4a.z2utils patches CMFDynamicViewFTI to get the list of available views from an IDynamicallyViewable adapter lookup. (dateable.chronos uses this mechanism for its folder calendar views). So my question becomes:

Is there a way to do this one-off display menu tweaking without changing a content type's FTI and without patching Plone?


The plone display menu builder uses ISelectableBrowserDefault to get available options in the Display menu (see http://dev.plone.org/plone/browser/plone.app.contentmenu/trunk/plone/app/contentmenu/menu.py#L220)

So I think (but I haven't tried this) that if you define an adapter for a more specific interface (in your case IMySpecialFolder) that provides the Products.CMFDynamicViewFTI.interface.ISelectableBrowserDefault it should work.

The adapter should have the methods required by plone.app.contentmenu.menu.DisplayMenu above.


Answering my own question, I've realised that the most straightforward way to achieve one-off folder views is to follow the pattern Plone itself applies in the Members folder: a PythonScript index_html that calls the custom view, e.g.

member_search=context.restrictedTraverse('member_search_form')
return member_search()

Products.CMFPlone illustrates how to setup such a PythonScript with a GenericSetup import handler.

In retrospect I realise I didn't need the marker interface in my question scenario. It's not necessary here in the answer either.

Note that this solution doesn't result in "the folder's display menu listing only my special case view" as I asked, but does away with the display menu altogether. I'm fine with that.


One way you could have solved it is using traversalhook to register menu items, or in this case, unregister menu items, or register menu items with conditions that make them not appear. With the traversal hook you can use a marker interface to make it just happen in a certain folder, subsection or page. You can see where we implemented similar code here

https://github.com/collective/collective.listingviews/blob/master/src/collective/listingviews/browser/views/controlpanel.py#L105

In this case we just wanted to register new display menu items dynamically based on control panel configuration.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜