[Checkins] SVN: zope.app.publisher/trunk/ Add possibility to specify custom item class in menuItem directives.
Dan Korostelev
nadako at gmail.com
Thu Nov 6 07:31:25 EST 2008
Log message for revision 92812:
Add possibility to specify custom item class in menuItem directives.
Changed:
U zope.app.publisher/trunk/CHANGES.txt
U zope.app.publisher/trunk/src/zope/app/publisher/browser/menu.txt
U zope.app.publisher/trunk/src/zope/app/publisher/browser/menumeta.py
U zope.app.publisher/trunk/src/zope/app/publisher/browser/metadirectives.py
-=-
Modified: zope.app.publisher/trunk/CHANGES.txt
===================================================================
--- zope.app.publisher/trunk/CHANGES.txt 2008-11-06 10:26:36 UTC (rev 92811)
+++ zope.app.publisher/trunk/CHANGES.txt 2008-11-06 12:31:23 UTC (rev 92812)
@@ -5,7 +5,8 @@
3.5.3 (Unreleased)
==================
-- ...
+- Added possibility to specify custom item class in menuItem, subMenuItem
+ and addMenuItem directives using the ``item_class`` argument (LP #291865).
3.5.2a1 (2008-10-23)
====================
Modified: zope.app.publisher/trunk/src/zope/app/publisher/browser/menu.txt
===================================================================
--- zope.app.publisher/trunk/src/zope/app/publisher/browser/menu.txt 2008-11-06 10:26:36 UTC (rev 92811)
+++ zope.app.publisher/trunk/src/zope/app/publisher/browser/menu.txt 2008-11-06 12:31:23 UTC (rev 92812)
@@ -587,7 +587,54 @@
<InterfaceClass __builtin__.TestMenuItemType>,
'View')]
+Custom menu item classes
+~~~~~~~~~~~~~~~~~~~~~~~~
+We can register menu items and sub menu items with custom classes instead
+of ones used by default. For that, we need to create an implementation
+of IBrowserMenuItem or IBrowserSubMenuItem.
+
+ >>> context = Context()
+ >>> items = menumeta.menuItemsDirective(context, TestMenuItemType, ITest)
+ >>> context.actions
+ []
+
+Let's create a custom menu item class that inherits standard BrowserMenuItem:
+
+ >>> class MyMenuItem(menu.BrowserMenuItem):
+ ... pass
+
+ >>> items.menuItem(context, u'view.html', 'View', item_class=MyMenuItem)
+
+Also create a custom sub menu item class inheriting standard BrowserSubMenuItem:
+
+ >>> class MySubMenuItem(menu.BrowserSubMenuItem):
+ ... pass
+
+ >>> items.subMenuItem(context, SaveOptions, 'Save', item_class=MySubMenuItem)
+
+ >>> actions = sorted(context.actions, key=lambda a:a['discriminator'])
+ >>> factories = [action['args'][1] for action in actions][-2:]
+
+ >>> factories[0].factory is MySubMenuItem
+ True
+
+ >>> factories[1].factory is MyMenuItem
+ True
+
+These directive will fail if you provide an item_class that does not
+implement IBrowserMenuItem/IBrowserSubMenuItem:
+
+ >>> items.menuItem(context, u'fail', 'Failed', item_class=object)
+ Traceback (most recent call last):
+ ...
+ ValueError: Item class (<type 'object'>) must implement IBrowserMenuItem
+
+ >>> items.subMenuItem(context, SaveOptions, 'Failed', item_class=object)
+ Traceback (most recent call last):
+ ...
+ ValueError: Item class (<type 'object'>) must implement IBrowserSubMenuItem
+
``ManagementViewSelector``
~~~~~~~~~~~~~~~~~~~~~~~~~~
Modified: zope.app.publisher/trunk/src/zope/app/publisher/browser/menumeta.py
===================================================================
--- zope.app.publisher/trunk/src/zope/app/publisher/browser/menumeta.py 2008-11-06 10:26:36 UTC (rev 92811)
+++ zope.app.publisher/trunk/src/zope/app/publisher/browser/menumeta.py 2008-11-06 12:31:23 UTC (rev 92812)
@@ -31,6 +31,7 @@
from zope.app.publisher.browser.menu import BrowserMenuItem, BrowserSubMenuItem
from zope.app.publisher.interfaces.browser import IBrowserMenu
from zope.app.publisher.interfaces.browser import IBrowserMenuItem
+from zope.app.publisher.interfaces.browser import IBrowserSubMenuItem
from zope.app.publisher.interfaces.browser import IMenuItemType
from zope.app.publisher.interfaces.browser import AddMenu
@@ -106,21 +107,21 @@
def menuItemDirective(_context, menu, for_,
action, title, description=u'', icon=None, filter=None,
permission=None, layer=IDefaultBrowserLayer, extra=None,
- order=0):
+ order=0, item_class=None):
"""Register a single menu item."""
return menuItemsDirective(_context, menu, for_, layer).menuItem(
_context, action, title, description, icon, filter,
- permission, extra, order)
+ permission, extra, order, item_class)
def subMenuItemDirective(_context, menu, for_, title, submenu,
action=u'', description=u'', icon=None, filter=None,
permission=None, layer=IDefaultBrowserLayer,
- extra=None, order=0):
+ extra=None, order=0, item_class=None):
"""Register a single sub-menu menu item."""
return menuItemsDirective(_context, menu, for_, layer).subMenuItem(
_context, submenu, title, description, action, icon, filter,
- permission, extra, order)
+ permission, extra, order, item_class)
class MenuItemFactory(object):
@@ -159,7 +160,8 @@
self.permission = permission
def menuItem(self, _context, action, title, description=u'',
- icon=None, filter=None, permission=None, extra=None, order=0):
+ icon=None, filter=None, permission=None, extra=None,
+ order=0, item_class=None):
if filter is not None:
filter = Engine.compile(filter)
@@ -171,8 +173,14 @@
order = _order_counter.get(self.for_, 1)
_order_counter[self.for_] = order + 1
+ if item_class is None:
+ item_class = self.menuItemClass
+
+ if not IBrowserMenuItem.implementedBy(item_class):
+ raise ValueError("Item class (%s) must implement IBrowserMenuItem" % item_class)
+
factory = MenuItemFactory(
- self.menuItemClass,
+ item_class,
title=title, description=description, icon=icon, action=action,
filter=filter, permission=permission, extra=extra, order=order,
_for=self.for_)
@@ -181,7 +189,7 @@
def subMenuItem(self, _context, submenu, title, description=u'',
action=u'', icon=None, filter=None, permission=None,
- extra=None, order=0):
+ extra=None, order=0, item_class=None):
if filter is not None:
filter = Engine.compile(filter)
@@ -193,8 +201,14 @@
order = _order_counter.get(self.for_, 1)
_order_counter[self.for_] = order + 1
+ if item_class is None:
+ item_class = self.subMenuItemClass
+
+ if not IBrowserSubMenuItem.implementedBy(item_class):
+ raise ValueError("Item class (%s) must implement IBrowserSubMenuItem" % item_class)
+
factory = MenuItemFactory(
- self.subMenuItemClass,
+ item_class,
title=title, description=description, icon=icon, action=action,
filter=filter, permission=permission, extra=extra, order=order,
_for=self.for_, submenuId=submenu)
@@ -230,7 +244,7 @@
def addMenuItem(_context, title, description='', menu=None, for_=None,
class_=None, factory=None, view=None, icon=None, filter=None,
permission=None, layer=IDefaultBrowserLayer, extra=None,
- order=0):
+ order=0, item_class=None):
"""Create an add menu item for a given class or factory
As a convenience, a class can be provided, in which case, a
@@ -288,4 +302,4 @@
return menuItemsDirective(_context, menu, for_, layer=layer).menuItem(
_context, action, title, description, icon, filter,
- permission, extra, order)
+ permission, extra, order, item_class)
Modified: zope.app.publisher/trunk/src/zope/app/publisher/browser/metadirectives.py
===================================================================
--- zope.app.publisher/trunk/src/zope/app/publisher/browser/metadirectives.py 2008-11-06 10:26:36 UTC (rev 92811)
+++ zope.app.publisher/trunk/src/zope/app/publisher/browser/metadirectives.py 2008-11-06 12:31:23 UTC (rev 92812)
@@ -494,6 +494,13 @@
default=0
)
+ item_class = GlobalObject(
+ title=u"Menu item class",
+ description=u"""
+ A class to be used as a factory for creating menu item""",
+ required=False
+ )
+
class IMenuItemSubdirective(IMenuItem):
"""Define a menu item within a group of menu items"""
More information about the Checkins
mailing list