Custom Add… Menu Action

I should expand on this more, but here’s a quick note about something I just did in a project I’m working on that may help some other people:

You know that Add… menu in the green bar when you have edit privileges on a page (I think the actual permission is ‘Modify portal content’)?

Have you ever wanted to replace the default call to portal_factory, via the createObject script with something else? Maybe a custom browser view that will create an object or give the user something else to do? (in my case it was ‘create a contact’ or ‘associate some existing contacts’).

Trying to use the five tag in zcml doesn’t work (it does work, however, to add new items to the display menu).

This does (at least in plone 4.0+, should also apply to 3.5). Given a standard plone egg-based product called my.product:

In my/product, add the following:

  • overrides.zcml
  • a menu module, I used a package, you can just use menu.py

In overrides.zcml:

<configure
    xmlns="http://namespaces.zope.org/zope"
    xmlns:five="http://namespaces.zope.org/five"
    xmlns:i18n="http://namespaces.zope.org/i18n"
    xmlns:gs="http://namespaces.zope.org/genericsetup" 
    xmlns:browser="http://namespaces.zope.org/browser"
    i18n_domain="blitzen.services">
  
   <browser:menu
    id="plone_contentmenu_factory"
    title="The 'add' menu - allows the user to add new content items in the context"
    class=".menu.MyFactoriesMenu"
    />
           
</configure>

In menu.py:


from plone.app.contentmenu.menu import FactoriesMenu, FactoriesSubMenuItem

class MyFactoriesMenu(FactoriesMenu):
    """
    Overload factories menu to do fancy stuff with adding new contacts
    """
    
    def getMenuItems(self, context, request):
        # menuitems is a list of tal-friendly dictionaries
        menuitems = super(MyFactoriesMenu, self).getMenuItems(context, request)
        
        # we only want to pull these contact switcheroo shenanagians 
        # if we're on a workspace object
        if context.portal_type != 'Workspace':
            return menuitems
        
        new_items = []
        
        for item in menuitems:
            if item.get('id', False) == 'Contact':
                new_item = item.copy()
                new_item['action'] = "%s/@@new_contact" % (context.absolute_url())
                new_items.append(new_item)
            else:
                new_items.append(item)
        
        return new_items
    

There you go. Restart Zope and it should be using your menu items class instead of Plone’s. You can do whatever you want in there, change the order of the items, remove some, inject new ones, etc. See plone.app.contentmenu.menu‘s configure.zcml file for more explaination, and the FactoriesMenu class for more information about what the list of dictionaries returned by getMenuItems is expecting.

One note: menus are aggressively cached in plone, so you might have to restart the app server where you’d normally just use plone.reload. Enjoy!

One other note: there are adapters you can override to do full-blown customizations. This approach seems a bit weird to me but I think it’s sound for the use case (I just want to override the createObject link in the menu).

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

4 Responses to Custom Add… Menu Action

  1. David Glick says:

    In Plone 4 there’s a much easier way to achieve this. You can simply go to the type in portal_types in the ZMI, and change the “Add view URL (Expression)” to string:${object/absolute_url}/@@new_contact

    This also works in Plone 3 if you have Dexterity installed (Dexterity monkey-patches the menu to work in the same way as in Plone 4).

    • jjmojojjmojo says:

      I saw that in the ZMI and wasn’t sure what it was. So that means adding string:${object/absolute_url}/@@new_contact to my FTI in profiles/default/types/Contact.xml should work as well?

  2. keul says:

    I was not aware of Plone 4 feature!

    For Plone 3 (and 4) I taken more or less what you are blogging about and made redturtle.custommenu.factories product.

  3. humbhenri says:

    Nice, thanks for the help

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s