[Checkins] SVN: Sandbox/nadako/zope.app.publisher/ Use zope.browsermenu.

Dan Korostelev nadako at gmail.com
Mon Aug 24 10:45:16 EDT 2009


Log message for revision 103154:
  Use zope.browsermenu.

Changed:
  U   Sandbox/nadako/zope.app.publisher/CHANGES.txt
  U   Sandbox/nadako/zope.app.publisher/buildout.cfg
  U   Sandbox/nadako/zope.app.publisher/setup.py
  U   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/configure.zcml
  U   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/fields.py
  U   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/managementviewselector.py
  U   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/menu.py
  D   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/menu.txt
  U   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/menumeta.py
  U   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/meta.zcml
  U   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/metadirectives.py
  D   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/addmenuitems.zcml
  D   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/menus-permissions.zcml
  D   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/menus.zcml
  D   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/menutestlayer.zcml
  U   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/support.py
  D   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_addMenuItem.py
  U   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_directives.py
  D   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_fields.py
  D   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_menu.py
  D   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_menudirectives.py
  D   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_menutestlayer.py
  U   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/viewmeta.py
  U   Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/interfaces/browser.py

-=-
Modified: Sandbox/nadako/zope.app.publisher/CHANGES.txt
===================================================================
--- Sandbox/nadako/zope.app.publisher/CHANGES.txt	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/CHANGES.txt	2009-08-24 14:45:16 UTC (rev 103154)
@@ -14,6 +14,8 @@
      package so zope.browserresource doesn't depend on any templating system.
      See zope.ptresource's CHANGES.txt for more information.
 
+   * ``zope.browsermenu`` - the menu mechanism was moved here completely.
+
 Backward-compatibility imports are provided, so there should not be much impact
 for those who uses old imports.
 

Modified: Sandbox/nadako/zope.app.publisher/buildout.cfg
===================================================================
--- Sandbox/nadako/zope.app.publisher/buildout.cfg	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/buildout.cfg	2009-08-24 14:45:16 UTC (rev 103154)
@@ -1,5 +1,8 @@
 [buildout]
-develop = . ../zope.browserresource ../zope.ptresource
+develop = .
+  ../zope.browserresource
+  ../zope.ptresource
+  ../zope.browsermenu
 parts = test coverage-test coverage-report
 
 [test]

Modified: Sandbox/nadako/zope.app.publisher/setup.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/setup.py	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/setup.py	2009-08-24 14:45:16 UTC (rev 103154)
@@ -60,6 +60,7 @@
                         'zope.app.pagetemplate',
                         'zope.browserresource',
                         'zope.ptresource',
+                        'zope.browsermenu',
                         ],
       extras_require={
           'test': ['zope.testing',

Modified: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/configure.zcml
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/configure.zcml	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/configure.zcml	2009-08-24 14:45:16 UTC (rev 103154)
@@ -5,6 +5,7 @@
 
   <include package="zope.browserresource" />
   <include package="zope.ptresource" />
+  <include package="zope.browsermenu" />
 
 <adapter
     factory=".ModifiableBrowserLanguages"
@@ -12,9 +13,6 @@
     provides="zope.i18n.interfaces.IModifiableUserPreferredLanguages"
     />
 
-<interface
-  interface="zope.app.publisher.interfaces.browser.IMenuItemType" />
-
 <utility
     name="Browser Skins"
     component=".vocabulary.BrowserSkinsVocabulary"
@@ -59,13 +57,4 @@
     allowed_interface="zope.publisher.interfaces.browser.IBrowserPublisher"
     />
 
-<!-- Menu access -->
-<browser:page
-    for="*"
-    name="view_get_menu"
-    permission="zope.Public"
-    class=".menu.MenuAccessView"
-    allowed_interface="zope.app.publisher.interfaces.browser.IMenuAccessView"
-    />
-
 </configure>

Modified: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/fields.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/fields.py	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/fields.py	2009-08-24 14:45:16 UTC (rev 103154)
@@ -15,94 +15,4 @@
 
 $Id$
 """
-__docformat__ = 'restructuredtext'
-
-import zope.component
-import zope.schema
-from zope.component.interfaces import ComponentLookupError
-from zope.configuration.exceptions import ConfigurationError
-from zope.configuration.fields import GlobalObject
-from zope.app.publisher.interfaces.browser import IMenuItemType
-
-
-class MenuField(GlobalObject):
-    r"""This fields represents a menu (item type).
-
-    Besides being able to look up the menu by importing it, we also try
-    to look up the name in the site manager.
-
-    >>> from zope.interface import directlyProvides
-    >>> from zope.interface.interface import InterfaceClass
-
-    >>> menu1 = InterfaceClass('menu1', (),
-    ...                        __doc__='Menu Item Type: menu1',
-    ...                        __module__='zope.app.menus')
-    >>> directlyProvides(menu1, IMenuItemType)
-
-    >>> menus = None
-    >>> class Resolver(object):
-    ...     def resolve(self, path):
-    ...         if path.startswith('zope.app.menus') and \
-    ...             hasattr(menus, 'menu1') or \
-    ...             path == 'zope.app.publisher.menus.menu1':
-    ...             return menu1
-    ...         raise ConfigurationError('menu1')
-
-    >>> field = MenuField()
-    >>> field = field.bind(Resolver())
-
-    Test 1: Import the menu
-    -----------------------
-
-    >>> field.fromUnicode('zope.app.publisher.menus.menu1') is menu1
-    True
-
-    Test 2: We have a shortcut name. Import the menu from `zope.app.menus1`.
-    ------------------------------------------------------------------------
-
-    >>> from types import ModuleType as module
-    >>> import sys
-    >>> menus = module('menus')
-    >>> old = sys.modules.get('zope.app.menus', None)
-    >>> sys.modules['zope.app.menus'] = menus
-    >>> setattr(menus, 'menu1', menu1)
-
-    >>> field.fromUnicode('menu1') is menu1
-    True
-
-    >>> if old is not None:
-    ...     sys.modules['zope.app.menus'] = old
-
-    Test 3: Get the menu from the Site Manager
-    ------------------------------------------
-    
-    >>> from zope.app.testing import ztapi
-    >>> ztapi.provideUtility(IMenuItemType, menu1, 'menu1')
-
-    >>> field.fromUnicode('menu1') is menu1
-    True
-    """
-
-    def fromUnicode(self, u):
-        name = str(u.strip())
-
-        try:
-            value = zope.component.queryUtility(IMenuItemType, name)
-        except ComponentLookupError:
-            # The component architecture is not up and running.
-            pass
-        else: 
-            if value is not None:
-                self.validate(value)
-                return value
-
-        try:
-            value = self.context.resolve('zope.app.menus.'+name)
-        except ConfigurationError, v:
-            try:
-                value = self.context.resolve(name)
-            except ConfigurationError, v:
-                raise zope.schema.ValidationError(v)
-        
-        self.validate(value)
-        return value
+from zope.browsermenu.field import MenuField # BBB import

Modified: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/managementviewselector.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/managementviewselector.py	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/managementviewselector.py	2009-08-24 14:45:16 UTC (rev 103154)
@@ -18,7 +18,7 @@
 from zope.interface import implements
 from zope.publisher.interfaces.browser import IBrowserPublisher
 from zope.publisher.browser import BrowserView
-from zope.app.publisher.browser.menu import getFirstMenuItem
+from zope.browsermenu.menu import getFirstMenuItem
 
 class ManagementViewSelector(BrowserView):
     """View that selects the first available management view.

Modified: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/menu.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/menu.py	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/menu.py	2009-08-24 14:45:16 UTC (rev 103154)
@@ -15,197 +15,12 @@
 
 $Id$
 """
-__docformat__ = "reStructuredText"
-import sys
-
-from zope.component import getAdapters
-from zope.component import getUtility
-from zope.interface import Interface
-from zope.interface import implements
-from zope.interface import providedBy
-from zope.interface.interfaces import IInterface
-from zope.pagetemplate.engine import Engine
-from zope.publisher.browser import BrowserView
-from zope.security import canAccess
-from zope.security import checkPermission
-from zope.security.interfaces import Forbidden
-from zope.security.interfaces import Unauthorized
-from zope.security.proxy import removeSecurityProxy
-from zope.traversing.publicationtraverse import PublicationTraverser
-
-from zope.app.publisher.interfaces.browser import IMenuAccessView
-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
-
-class BrowserMenu(object):
-    """Browser Menu"""
-    implements(IBrowserMenu)
-
-    def __init__(self, id, title=u'', description=u''):
-        self.id = id
-        self.title = title
-        self.description = description
-
-    def getMenuItemType(self):
-        return getUtility(IMenuItemType, self.id)
-
-    def getMenuItems(self, object, request):
-        """Return menu item entries in a TAL-friendly form."""
-
-        result = []
-        for name, item in getAdapters((object, request),
-                                      self.getMenuItemType()):
-            if item.available():
-                result.append(item)
-
-        # Now order the result. This is not as easy as it seems.
-        #
-        # (1) Look at the interfaces and put the more specific menu entries
-        #     to the front. 
-        # (2) Sort unambigious entries by order and then by title.
-        ifaces = list(providedBy(removeSecurityProxy(object)).__iro__)
-        max_key = len(ifaces)
-        def iface_index(item):
-            iface = item._for
-            if not iface:
-                iface = Interface
-            if IInterface.providedBy(iface):
-                return ifaces.index(iface)
-            if isinstance(removeSecurityProxy(object), item._for):
-                # directly specified for class, this goes first.
-                return -1
-            # no idea. This goes last.
-            return max_key
-        result = [(iface_index(item), item.order, item.title, item)
-                  for item in result]
-        result.sort()
-
-        result = [
-            {'title': title,
-             'description': item.description,
-             'action': item.action,
-             'selected': (item.selected() and u'selected') or u'',
-             'icon': item.icon,
-             'extra': item.extra,
-             'submenu': (IBrowserSubMenuItem.providedBy(item) and
-                         getMenu(item.submenuId, object, request)) or None}
-            for index, order, title, item in result]
-
-        return result
-
-
-class BrowserMenuItem(BrowserView):
-    """Browser Menu Item Class"""
-    implements(IBrowserMenuItem)
-
-    # See zope.app.publisher.interfaces.browser.IBrowserMenuItem
-    title = u''
-    description = u''
-    action = u''
-    extra = None
-    order = 0
-    permission = None
-    filter = None
-    icon = None
-    _for = Interface
-
-    def available(self):
-        """See zope.app.publisher.interfaces.browser.IBrowserMenuItem"""
-        # Make sure we have the permission needed to access the menu's action
-        if self.permission is not None:
-            # If we have an explicit permission, check that we
-            # can access it.
-            if not checkPermission(self.permission, self.context):
-                return False
-
-        elif self.action != u'':
-            # Otherwise, test access by attempting access
-            path = self.action
-            l = self.action.find('?')
-            if l >= 0:
-                path = self.action[:l]
-
-            traverser = PublicationTraverser()
-            try:
-                view = traverser.traverseRelativeURL(
-                    self.request, self.context, path)
-            except (Unauthorized, Forbidden, LookupError):
-                return False
-            else:
-                # we're assuming that view pages are callable
-                # this is a pretty sound assumption
-                if not canAccess(view, '__call__'):
-                    return False
-
-        # Make sure that we really want to see this menu item
-        if self.filter is not None:
-
-            try:
-                include = self.filter(Engine.getContext(
-                    context = self.context,
-                    nothing = None,
-                    request = self.request,
-                    modules = sys.modules,
-                    ))
-            except Unauthorized:
-                return False
-            else:
-                if not include:
-                    return False
-
-        return True
-
-    def selected(self):
-        """See zope.app.publisher.interfaces.browser.IBrowserMenuItem"""
-        request_url = self.request.getURL()
-
-        normalized_action = self.action
-        if self.action.startswith('@@'):
-            normalized_action = self.action[2:]
-
-        if request_url.endswith('/'+normalized_action):
-            return True
-        if request_url.endswith('/++view++'+normalized_action):
-            return True
-        if request_url.endswith('/@@'+normalized_action):
-            return True
-
-        return False
-
-
-class BrowserSubMenuItem(BrowserMenuItem):
-    """Browser Menu Item Base Class"""
-    implements(IBrowserSubMenuItem)
-
-    # See zope.app.publisher.interfaces.browser.IBrowserSubMenuItem
-    submenuId = None
-
-    def selected(self):
-        """See zope.app.publisher.interfaces.browser.IBrowserMenuItem"""
-        if self.action is u'':
-            return False
-        return super(BrowserSubMenuItem, self).selected()
-
-
-def getMenu(id, object, request):
-    """Return menu item entries in a TAL-friendly form."""
-    menu = getUtility(IBrowserMenu, id)
-    return menu.getMenuItems(object, request)
-
-
-def getFirstMenuItem(id, object, request):
-    """Get the first item of a menu."""
-    items = getMenu(id, object, request)
-    if items:
-        return items[0]
-    return None
-
-
-class MenuAccessView(BrowserView):
-    """A view allowing easy access to menus."""
-    implements(IMenuAccessView)
-
-    def __getitem__(self, menuId):
-        return getMenu(menuId, self.context, self.request)
+# BBB imports
+from zope.browsermenu.menu import (
+    BrowserMenu,
+    BrowserMenuItem,
+    BrowserSubMenuItem,
+    getMenu,
+    getFirstMenuItem,
+    MenuAccessView,
+)

Deleted: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/menu.txt
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/menu.txt	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/menu.txt	2009-08-24 14:45:16 UTC (rev 103154)
@@ -1,697 +0,0 @@
-=============
-Browser Menus
-=============
-
-Browser menus are used to categorize browser actions, such as the views of a
-content component or the addable components of a container. In essence they
-provide the same functionality as menu bars in desktop application.
-
-  >>> from zope.app.publisher.browser import menu, menumeta
-
-Menus are simple components that have an id, title and description. They also
-must provide a method called ``getMenuItems(object, request)`` that returns a
-TAL-friendly list of information dictionaries. We will see this in detail
-later. The default menu implementation, however, makes the menu be very
-transparent by identifying the menu through an interface. So let's define and
-register a simple edit menu:
-
-  >>> import zope.interface
-  >>> class EditMenu(zope.interface.Interface):
-  ...     """This is an edit menu."""
-
-  >>> from zope.app.publisher.interfaces.browser import IMenuItemType
-  >>> zope.interface.directlyProvides(EditMenu, IMenuItemType)
-
-  >>> from zope.app.testing import ztapi
-  >>> ztapi.provideUtility(IMenuItemType, EditMenu, 'edit')
-
-Now we have to create and register the menu itself:
-
-  >>> from zope.app.publisher.interfaces.browser import IBrowserMenu
-  >>> ztapi.provideUtility(
-  ...     IBrowserMenu, menu.BrowserMenu('edit', u'Edit', u'Edit Menu'), 'edit')
-
-Note that these steps seem like a lot of boilerplate, but all this work is
-commonly done for you via ZCML. An item in a menu is simply an adapter that
-provides. In the following section we will have a closer look at the browser
-menu item:
-
-``BrowserMenuItem`` class
--------------------------
-
-The browser menu item represents an entry in the menu. Essentially, the menu
-item is a browser view of a content component. Thus we have to create a
-content component first:
-
-  >>> class IContent(zope.interface.Interface):
-  ...     pass
-
-  >>> from zope.publisher.interfaces.browser import IBrowserPublisher
-  >>> from zope.security.interfaces import Unauthorized, Forbidden
-
-  >>> class Content(object):
-  ...     zope.interface.implements(IContent, IBrowserPublisher)
-  ...
-  ...     def foo(self):
-  ...         pass
-  ...
-  ...     def browserDefault(self, r):
-  ...         return self, ()
-  ...
-  ...     def publishTraverse(self, request, name):
-  ...         if name.startswith('fb'):
-  ...             raise Forbidden, name
-  ...         if name.startswith('ua'):
-  ...             raise Unauthorized, name
-  ...         if name.startswith('le'):
-  ...             raise LookupError, name
-  ...         return self.foo
-
-We also implemented the ``IBrowserPublisher`` interface, because we want to
-make the object traversable, so that we can make availability checks later.
-
-Since the ``BrowserMenuItem`` is just a view, we can initiate it with an
-object and a request.
-
-  >>> from zope.publisher.browser import TestRequest
-  >>> item = menu.BrowserMenuItem(Content(), TestRequest())
-
-Note that the menu item knows *nothing* about the menu itself. It purely
-depends on the adapter registration to determine in which menu it will
-appear. The advantage is that a menu item can be reused in several menus.
-
-Now we add a title, description, order and icon and see whether we can then
-access the value. Note that these assignments are always automatically done by
-the framework.
-
-  >>> item.title = u'Item 1'
-  >>> item.title
-  u'Item 1'
-
-  >>> item.description = u'This is Item 1.'
-  >>> item.description
-  u'This is Item 1.'
-
-  >>> item.order
-  0
-  >>> item.order = 1
-  >>> item.order
-  1
-
-  >>> item.icon is None
-  True
-  >>> item.icon = u'/@@/icon.png'
-  >>> item.icon
-  u'/@@/icon.png'
-
-Since there is no permission or view specified yet, the menu item should
-be available and not selected.
-
-  >>> item.available()
-  True
-  >>> item.selected()
-  False
-
-There are two ways to deny availability of a menu item: (1) the current
-user does not have the correct permission to access the action or the menu
-item itself, or (2) the filter returns ``False``, in which case the menu
-item should also not be shown. 
-
-  >>> from zope.security.interfaces import IPermission
-  >>> from zope.security.permission import Permission
-  >>> from zope.app.testing import ztapi
-  >>> perm = Permission('perm', 'Permission')
-  >>> ztapi.provideUtility(IPermission, perm, 'perm')
-
-  >>> class ParticipationStub(object):
-  ...     principal = 'principal'
-  ...     interaction = None
-
-
-In the first case, the permission of the menu item was explicitely
-specified. Make sure that the user needs this permission to make the menu
-item available.
-
-  >>> item.permission = perm
-
-Now, we are not setting any user. This means that the menu item should be
-available.
-
-  >>> from zope.security.management import newInteraction, endInteraction
-  >>> endInteraction()
-  >>> newInteraction()
-  >>> item.available()
-  True
-
-Now we specify a principal that does not have the specified permission.
-
-  >>> endInteraction()
-  >>> newInteraction(ParticipationStub())
-  >>> item.available()
-  False
-
-In the second case, the permission is not explicitely defined and the
-availability is determined by the permission required to access the
-action.
-
-  >>> item.permission = None
-
-  All views starting with 'fb' are forbidden, the ones with 'ua' are
-  unauthorized and all others are allowed.
-
-  >>> item.action = u'fb'
-  >>> item.available()
-  False
-  >>> item.action = u'ua'
-  >>> item.available()
-  False
-  >>> item.action = u'a'
-  >>> item.available()
-  True
-
-Also, sometimes a menu item might be registered for a view that does not
-exist. In those cases the traversal mechanism raises a `TraversalError`, which
-is a special type of `LookupError`. All actions starting with `le` should
-raise this error:
-
-  >>> item.action = u'le'
-  >>> item.available()
-  False
-
-Now let's test filtering. If the filter is specified, it is assumed to be
-a TALES obejct.
-
-  >>> from zope.pagetemplate.engine import Engine
-  >>> item.action = u'a'
-  >>> item.filter = Engine.compile('not:context')
-  >>> item.available()
-  False
-  >>> item.filter = Engine.compile('context')
-  >>> item.available()
-  True
-
-Finally, make sure that the menu item can be selected.
-
-  >>> item.request = TestRequest(SERVER_URL='http://127.0.0.1/@@view.html',
-  ...                            PATH_INFO='/@@view.html')
-
-  >>> item.selected()
-  False
-  >>> item.action = u'view.html'
-  >>> item.selected()
-  True
-  >>> item.action = u'@@view.html'
-  >>> item.selected()
-  True
-  >>> item.request = TestRequest(
-  ...     SERVER_URL='http://127.0.0.1/++view++view.html',
-  ...     PATH_INFO='/++view++view.html')
-  >>> item.selected()
-  True
-  >>> item.action = u'otherview.html'
-  >>> item.selected()
-  False
-
-
-``BrowserSubMenuItem`` class
-----------------------------
-
-The menu framework also allows for submenus. Submenus can be inserted by
-creating a special menu item that simply points to another menu to be
-inserted:
-
-  >>> item = menu.BrowserSubMenuItem(Content(), TestRequest())
-
-The framework will always set the sub-menu automatically (we do it
-manually here):
-
-  >>> class SaveOptions(zope.interface.Interface):
-  ...     "A sub-menu that describes available save options for the content."
-
-  >>> zope.interface.directlyProvides(SaveOptions, IMenuItemType)
-
-  >>> ztapi.provideUtility(IMenuItemType, SaveOptions, 'save')
-  >>> ztapi.provideUtility(IBrowserMenu,
-  ...                      menu.BrowserMenu('save', u'Save', u'Save Menu'),
-  ...                      'save')
-
-Now we can assign the sub-menu id to the menu item: 
-
-  >>> item.submenuId = 'save'
-
-Also, the ``action`` attribute for the browser sub-menu item is optional,
-because you often do not want the item itself to represent something. The rest
-of the class is identical to the ``BrowserMenuItem`` class.
-
-
-Getting a Menu
---------------
-
-Now that we know how the single menu item works, let's have a look at how menu
-items get put together to a menu. But let's first create some menu items and
-register them as adapters with the component architecture.
-
-Register the edit menu entries first. We use the menu item factory to create
-the items:
-
-  >>> from zope.app.testing import ztapi
-  >>> from zope.publisher.interfaces.browser import IBrowserRequest
-
-  >>> undo = menumeta.MenuItemFactory(menu.BrowserMenuItem, title="Undo", 
-  ...                                 action="undo.html")
-  >>> ztapi.provideAdapter((IContent, IBrowserRequest), EditMenu, undo, 'undo')
-
-  >>> redo = menumeta.MenuItemFactory(menu.BrowserMenuItem, title="Redo",
-  ...                                 action="redo.html", icon="/@@/redo.png")
-  >>> ztapi.provideAdapter((IContent, IBrowserRequest), EditMenu, redo, 'redo')
-
-  >>> save = menumeta.MenuItemFactory(menu.BrowserSubMenuItem, title="Save", 
-  ...                                 submenuId='save', order=2)
-  >>> ztapi.provideAdapter((IContent, IBrowserRequest), EditMenu, save, 'save')
-
-And now the save options:
-
-  >>> saveas = menumeta.MenuItemFactory(menu.BrowserMenuItem, title="Save as", 
-  ...                                   action="saveas.html")
-  >>> ztapi.provideAdapter((IContent, IBrowserRequest), 
-  ...                      SaveOptions, saveas, 'saveas')
-
-  >>> saveall = menumeta.MenuItemFactory(menu.BrowserMenuItem, title="Save all",
-  ...                                    action="saveall.html")
-  >>> ztapi.provideAdapter((IContent, IBrowserRequest), 
-  ...                      SaveOptions, saveall, 'saveall')
-
-Note that we can also register menu items for classes:
-
-
-  >>> new = menumeta.MenuItemFactory(menu.BrowserMenuItem, title="New",
-  ...                                 action="new.html", _for=Content)
-  >>> ztapi.provideAdapter((Content, IBrowserRequest), EditMenu, new, 'new')
-
-
-The utility that is used to generate the menu into a TAL-friendly
-data-structure is ``getMenu()``::
-
-  getMenu(menuId, object, request)
-
-where ``menuId`` is the id originally specified for the menu. Let's look up the
-menu now:
-
-  >>> pprint(menu.getMenu('edit', Content(), TestRequest()))
-  [{'action': 'new.html',
-    'description': u'',
-    'extra': None,
-    'icon': None,
-    'selected': u'',
-    'submenu': None,
-    'title': 'New'},
-  {'action': 'redo.html',
-    'description': u'',
-    'extra': None,
-    'icon': '/@@/redo.png',
-    'selected': u'',
-    'submenu': None,
-    'title': 'Redo'},
-   {'action': 'undo.html',
-    'description': u'',
-    'extra': None,
-    'icon': None,
-    'selected': u'',
-    'submenu': None,
-    'title': 'Undo'},
-   {'action': u'',
-    'description': u'',
-    'extra': None,
-    'icon': None,
-    'selected': u'',
-    'submenu': [{'action': 'saveall.html',
-                 'description': u'',
-                 'extra': None,
-                 'icon': None,
-                 'selected': u'',
-                 'submenu': None,
-                 'title': 'Save all'},
-                {'action': 'saveas.html',
-                 'description': u'',
-                 'extra': None,
-                 'icon': None,
-                 'selected': u'',
-                 'submenu': None,
-                 'title': 'Save as'}],
-    'title': 'Save'}]
-
-
-Custom ``IBrowserMenu`` Implementations
----------------------------------------
-
-Until now we have only seen how to use the default menu implementation. Much
-of the above boilerplate was necessary just to support custom menus. But what
-could custom menus do? Sometimes menu items are dynamically generated based on
-a certain state of the object the menu is for. For example, you might want to
-show all items in a folder-like component. So first let's create this
-folder-like component:
-
-  >>> class Folderish(Content):
-  ...     names = ['README.txt', 'logo.png', 'script.py']
-
-Now we create a menu using the names to create a menu:
-
-  >>> from zope.app.publisher.interfaces.browser import IBrowserMenu
-
-  >>> class Items(object):
-  ...     zope.interface.implements(IBrowserMenu)
-  ...  
-  ...     def __init__(self, id, title=u'', description=u''):
-  ...         self.id = id
-  ...         self.title = title
-  ...         self.description = description
-  ...     
-  ...     def getMenuItems(self, object, request):
-  ...         return [{'title': name,
-  ...                  'description': None,
-  ...                  'action': name + '/manage',
-  ...                  'selected': u'',
-  ...                  'icon': None,
-  ...                  'extra': {},
-  ...                  'submenu': None}
-  ...                 for name in object.names]
-
-and register it:
-
-  >>> ztapi.provideUtility(IBrowserMenu,
-  ...                      Items('items', u'Items', u'Items Menu'),
-  ...                      'items')
-
-We can now get the menu items using the previously introduced API:
-
-  >>> pprint(menu.getMenu('items', Folderish(), TestRequest()))
-  [{'action': 'README.txt/manage',
-    'description': None,
-    'extra': {},
-    'icon': None,
-    'selected': u'',
-    'submenu': None,
-    'title': 'README.txt'},
-   {'action': 'logo.png/manage',
-    'description': None,
-    'extra': {},
-    'icon': None,
-    'selected': u'',
-    'submenu': None,
-    'title': 'logo.png'},
-   {'action': 'script.py/manage',
-    'description': None,
-    'extra': {},
-    'icon': None,
-    'selected': u'',
-    'submenu': None,
-    'title': 'script.py'}]
-
-
-``MenuItemFactory`` class
--------------------------
-
-As you have seen above already, we have used the menu item factory to generate
-adapter factories for menu items. The factory needs a particular
-``IBrowserMenuItem`` class to instantiate. Here is an example using a dummy
-menu item class:
-  
-  >>> class DummyBrowserMenuItem(object):
-  ...     "a dummy factory for menu items"
-  ...     def __init__(self, context, request):
-  ...         self.context = context
-  ...         self.request = request
-  
-To instantiate this class, pass the factory and the other arguments as keyword
-arguments (every key in the arguments should map to an attribute of the menu
-item class). We use dummy values for this example.
-  
-  >>> factory = menumeta.MenuItemFactory(
-  ...     DummyBrowserMenuItem, title='Title', description='Description', 
-  ...     icon='Icon', action='Action', filter='Filter', 
-  ...     permission='zope.Public', extra='Extra', order='Order', _for='For')
-  >>> factory.factory is DummyBrowserMenuItem
-  True
-  
-The "zope.Public" permission needs to be translated to ``CheckerPublic``.
-  
-  >>> from zope.security.checker import CheckerPublic
-  >>> factory.kwargs['permission'] is CheckerPublic
-  True
-  
-Call the factory with context and request to return the instance.  We continue
-to use dummy values.
-  
-  >>> item = factory('Context', 'Request')
-  
-The returned value should be an instance of the ``DummyBrowserMenuItem``, and
-have all of the values we initially set on the factory.
-  
-  >>> isinstance(item, DummyBrowserMenuItem)
-  True
-  >>> item.context
-  'Context'
-  >>> item.request
-  'Request'
-  >>> item.title
-  'Title'
-  >>> item.description
-  'Description'
-  >>> item.icon
-  'Icon'
-  >>> item.action
-  'Action'
-  >>> item.filter
-  'Filter'
-  >>> item.permission is CheckerPublic
-  True
-  >>> item.extra
-  'Extra'
-  >>> item.order
-  'Order'
-  >>> item._for
-  'For'
-  
-If you pass a permission other than ``zope.Public`` to the
-``MenuItemFactory``, it should pass through unmodified.
-  
-  >>> factory = menumeta.MenuItemFactory(
-  ...     DummyBrowserMenuItem, title='Title', description='Description', 
-  ...     icon='Icon', action='Action', filter='Filter', 
-  ...     permission='another.Permission', extra='Extra', order='Order', 
-  ...     _for='For_')
-  >>> factory.kwargs['permission']
-  'another.Permission'
-
-
-Directive Handlers
-------------------
-
-``menu`` Directive Handler
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Provides a new menu (item type).
-
-  >>> class Context(object):
-  ...     info = u'doc'
-  ...     def __init__(self): 
-  ...         self.actions = []
-  ...
-  ...     def action(self, **kw): 
-  ...         self.actions.append(kw)
-
-Possibility 1: The Old Way
-++++++++++++++++++++++++++
-  
-  >>> context = Context()
-  >>> menumeta.menuDirective(context, u'menu1', title=u'Menu 1')
-  >>> iface = context.actions[0]['args'][1]
-  >>> iface.getName()
-  u'menu1'
-
-  >>> import sys
-  >>> hasattr(sys.modules['zope.app.menus'], 'menu1')
-  True
-
-  >>> del sys.modules['zope.app.menus'].menu1
-
-Possibility 2: Just specify an interface
-++++++++++++++++++++++++++++++++++++++++
-
-  >>> class menu1(zope.interface.Interface):
-  ...     pass
-
-  >>> context = Context()
-  >>> menumeta.menuDirective(context, interface=menu1)
-  >>> context.actions[0]['args'][1] is menu1
-  True
-
-Possibility 3: Specify an interface and an id
-+++++++++++++++++++++++++++++++++++++++++++++
-
-  >>> context = Context()
-  >>> menumeta.menuDirective(context, id='menu1', interface=menu1)
-
-  >>> pprint([action['discriminator'] for action in context.actions])
-  [('browser', 'MenuItemType', '__builtin__.menu1'),
-   ('interface', '__builtin__.menu1'),
-   ('browser', 'MenuItemType', 'menu1'),
-   ('utility',
-    <InterfaceClass zope.app.publisher.interfaces.browser.IBrowserMenu>,
-    'menu1'),
-   None]
-   
-Here are some disallowed configurations.
-
-  >>> context = Context()
-  >>> menumeta.menuDirective(context)
-  Traceback (most recent call last):
-  ...
-  ConfigurationError: You must specify the 'id' or 'interface' attribute.
-
-  >>> menumeta.menuDirective(context, title='Menu 1')
-  Traceback (most recent call last):
-  ...
-  ConfigurationError: You must specify the 'id' or 'interface' attribute.
-
-
-``menuItems`` Directive Handler
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Register several menu items for a particular menu.
-
-  >>> class TestMenuItemType(zope.interface.Interface):
-  ...     pass
-
-  >>> class ITest(zope.interface.Interface): 
-  ...     pass
-
-  >>> context = Context()
-  >>> items = menumeta.menuItemsDirective(context, TestMenuItemType, ITest)
-  >>> context.actions
-  []
-  >>> items.menuItem(context, u'view.html', 'View')
-  >>> items.subMenuItem(context, SaveOptions, 'Save')
-
-  >>> disc = [action['discriminator'] for action in context.actions]
-  >>> disc.sort()
-  >>> pprint(disc[-2:])
-  [('adapter',
-    (<InterfaceClass __builtin__.ITest>,
-     <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-    <InterfaceClass __builtin__.TestMenuItemType>,
-    'Save'),
-   ('adapter',
-    (<InterfaceClass __builtin__.ITest>,
-     <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-    <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``
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Test the action (redirect url) of the first menu item and ensure that we don't
-redirect to the parent before we reach the item if we use actions like: '../'
-'javascript:popup()' or '++namespace++'.
-
-First setup the 'zmi_views' menu.
-
-  >>> class ZMIViews(zope.interface.Interface):
-  ...     """This is the zmi_views menu."""
-  >>> zope.interface.directlyProvides(ZMIViews, IMenuItemType)
-  >>> ztapi.provideUtility(IMenuItemType, ZMIViews, 'zmi_views')
-  >>> from zope.app.publisher.interfaces.browser import IBrowserMenu
-  >>> ztapi.provideUtility(
-  ...     IBrowserMenu, menu.BrowserMenu('zmi_views', u'ZMIViews', 
-  ...     u'ZMI Views'), 'zmi_views')
-
-Register some 'zmi_views' menu items.
-
-  >>> first = menumeta.MenuItemFactory(menu.BrowserMenuItem, title="First", 
-  ...     action="../")
-  >>> ztapi.provideAdapter((IContent, IBrowserRequest), ZMIViews, first, 
-  ...    'first')
-
-  >>> second = menumeta.MenuItemFactory(menu.BrowserMenuItem, title="Second", 
-  ...     action="second.html")
-  >>> ztapi.provideAdapter((IContent, IBrowserRequest), ZMIViews, second, 
-  ...    'second')
-
-Now create a new content object.
-
-  >>> content = Content()
-  >>> request = TestRequest(SERVER_URL='http://127.0.0.1/',
-  ...     PATH_INFO='/')
-
-Test the actions. Remember that this action get redirected before we traverse 
-to the content. This means actions like ``../`` will make it impossible to 
-access the view because the ``../`` will redirect us before we traverse.
-
-  >>> menus = menu.getMenu('zmi_views', content, request)
-  >>> [menu['action'] for menu in menus]
-  ['../', 'second.html']
-
-Now call the ManagementViewSelector view and we get a empty string as result.
-
-  >>> from zope.app.publisher.browser.managementviewselector import \
-  ...     ManagementViewSelector
-  >>> view = ManagementViewSelector(content, request)
-  >>> view()
-  u''
-
-Now check the more interesting redirect in the request. The redirect location
-is not like excpected '../'. We get '.' as the redirect location. This is 
-important otherwise we get redirected to the parent if we call the
-first menu item with actions like '../parentview.html' instead of traverse
-to the item.
-
-  >>> request.response.getHeader('Location')
-  '.'

Modified: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/menumeta.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/menumeta.py	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/menumeta.py	2009-08-24 14:45:16 UTC (rev 103154)
@@ -15,294 +15,13 @@
 
 $Id$
 """
-from zope.browser.interfaces import IAdding
-from zope.component import getGlobalSiteManager
-from zope.component import getUtility
-from zope.component.interface import provideInterface
-from zope.component.zcml import adapter
-from zope.component.zcml import proxify
-from zope.component.zcml import utility
-from zope.configuration.exceptions import ConfigurationError
-from zope.interface.interface import InterfaceClass
-from zope.interface import Interface
-from zope.pagetemplate.engine import Engine
-from zope.publisher.interfaces.browser import IDefaultBrowserLayer
-from zope.security.checker import InterfaceChecker, CheckerPublic
-from zope.security.metaconfigure import ClassDirective
-
-from zope.app.publisher.browser.menu import BrowserMenu
-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
-
-# Create special modules that contain all menu item types
-from types import ModuleType as module
-import sys
-menus = module('menus')
-sys.modules['zope.app.menus'] = menus
-
-
-_order_counter = {}
-
-
-def menuDirective(_context, id=None, class_=BrowserMenu, interface=None,
-                  title=u'', description=u''):
-    """Registers a new browser menu."""
-    if id is None and interface is None:
-        raise ConfigurationError(
-            "You must specify the 'id' or 'interface' attribute.")
-
-    if interface is None:
-        if id in dir(menus):
-            # reuse existing interfaces for the id, without this we are not
-            # able to override menus.
-            interface = getattr(menus, id)
-        else:
-            interface = InterfaceClass(id, (),
-                                       __doc__='Menu Item Type: %s' %id,
-                                       __module__='zope.app.menus')
-            # Add the menu item type to the `menus` module.
-            # Note: We have to do this immediately, so that directives using the
-            # MenuField can find the menu item type.
-            setattr(menus, id, interface)
-        path = 'zope.app.menus.' + id
-    else:
-        path = interface.__module__ + '.' + interface.getName()
-
-        # If an id was specified, make this menu available under this id.
-        # Note that the menu will be still available under its path, since it
-        # is an adapter, and the `MenuField` can resolve paths as well.
-        if id is None:
-            id = path
-        else:
-            # Make the interface available in the `zope.app.menus` module, so
-            # that other directives can find the interface under the name
-            # before the CA is setup.
-            _context.action(
-                discriminator = ('browser', 'MenuItemType', path),
-                callable = provideInterface,
-                args = (path, interface, IMenuItemType, _context.info)
-                )
-            setattr(menus, id, interface)
-
-    # Register the layer interface as an interface
-    _context.action(
-        discriminator = ('interface', path),
-        callable = provideInterface,
-        args = (path, interface),
-        kw = {'info': _context.info}
-        )
-
-    # Register the menu item type interface as an IMenuItemType
-    _context.action(
-        discriminator = ('browser', 'MenuItemType', id),
-        callable = provideInterface,
-        args = (id, interface, IMenuItemType, _context.info)
-        )
-
-    # Register the menu as a utility
-    utility(_context, IBrowserMenu, class_(id, title, description), name=id)
-
-
-def menuItemDirective(_context, menu, for_,
-                      action, title, description=u'', icon=None, filter=None,
-                      permission=None, layer=IDefaultBrowserLayer, extra=None,
-                      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, 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, 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, item_class)
-
-
-class MenuItemFactory(object):
-    """generic factory for menu items."""
-
-    def __init__(self, factory, **kwargs):
-        self.factory = factory
-        if 'permission' in kwargs and kwargs['permission'] == 'zope.Public':
-            kwargs['permission'] = CheckerPublic
-        self.kwargs = kwargs
-
-    def __call__(self, context, request):
-        item = self.factory(context, request)
-
-        for key, value in self.kwargs.items():
-            setattr(item, key, value)
-
-        if item.permission is not None:
-            checker = InterfaceChecker(IBrowserMenuItem, item.permission)
-            item = proxify(item, checker)
-
-        return item
-
-
-class menuItemsDirective(object):
-    """Register several menu items for a particular menu."""
-
-    menuItemClass = BrowserMenuItem
-    subMenuItemClass = BrowserSubMenuItem
-
-    def __init__(self, _context, menu, for_, layer=IDefaultBrowserLayer,
-                 permission=None):
-        self.for_ = for_
-        self.menuItemType = menu
-        self.layer = layer
-        self.permission = permission
-
-    def menuItem(self, _context, action, title, description=u'',
-                 icon=None, filter=None, permission=None, extra=None,
-                 order=0, item_class=None):
-
-        if filter is not None:
-            filter = Engine.compile(filter)
-
-        if permission is None:
-            permission = self.permission
-
-        if order == 0:
-            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(
-            item_class,
-            title=title, description=description, icon=icon, action=action,
-            filter=filter, permission=permission, extra=extra, order=order,
-            _for=self.for_)
-        adapter(_context, (factory,), self.menuItemType,
-                (self.for_, self.layer), name=title)
-
-    def subMenuItem(self, _context, submenu, title, description=u'',
-                    action=u'', icon=None, filter=None, permission=None,
-                    extra=None, order=0, item_class=None):
-
-        if filter is not None:
-            filter = Engine.compile(filter)
-
-        if permission is None:
-            permission = self.permission
-
-        if order == 0:
-            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(
-            item_class,
-            title=title, description=description, icon=icon, action=action,
-            filter=filter, permission=permission, extra=extra, order=order,
-            _for=self.for_, submenuId=submenu)
-        adapter(_context, (factory,), self.menuItemType,
-                (self.for_, self.layer), name=title)
-
-    def __call__(self, _context):
-        # Nothing to do.
-        pass
-
-def _checkViewFor(for_=None, layer=None, view_name=None):
-    """Check if there is a view of that name registered for IAdding
-    and IBrowserRequest. If not raise a ConfigurationError
-
-    It will raise a ConfigurationError if :
-        o view=""
-        o if view_name is not registred
-    """
-
-    if view_name is None:
-        raise ConfigurationError(
-            "Within a addMenuItem directive the view attribut"
-            " is optional but can\'t be empty"
-            )
-
-    gsm = getGlobalSiteManager()
-    if gsm.adapters.lookup((for_, layer),
-                           Interface, view_name) is None:
-        raise ConfigurationError(
-            "view name %s not found " %view_name
-            )
-
-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, 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
-    factory is automatically defined based on the class.  In this
-    case, the factory id is based on the class name.
-
-    """
-
-    if for_ is not None:
-        _context.action(
-            discriminator = None,
-            callable = provideInterface,
-            args = ('', for_)
-            )
-        forname = 'For' + for_.getName()
-    else:
-        for_ = IAdding
-        forname = ''
-
-    if menu is not None:
-        if isinstance(menu, (str, unicode)):
-            menu = getUtility(IMenuItemType, menu)
-            if menu is None:
-                raise ValueError("Missing menu id '%s'" % menu)
-
-    if class_ is None:
-        if factory is None:
-            raise ValueError("Must specify either class or factory")
-    else:
-        if factory is not None:
-            raise ValueError("Can't specify both class and factory")
-        if permission is None:
-            raise ValueError(
-                "A permission must be specified when a class is used")
-        factory = "BrowserAdd%s__%s.%s" % (
-            forname, class_.__module__, class_.__name__)
-        ClassDirective(_context, class_).factory(_context, id=factory)
-
-    extra = {'factory': factory}
-
-    if view:
-        action = view
-        # This action will check if the view exists
-        _context.action(
-            discriminator = None,
-            callable = _checkViewFor,
-            args = (for_, layer, view),
-            order=999999
-            )
-    else:
-        action = factory
-
-    if menu == None:
-        menu = AddMenu
-
-    return menuItemsDirective(_context, menu, for_, layer=layer).menuItem(
-        _context, action, title, description, icon, filter,
-        permission, extra, order, item_class)
+# BBB imports
+from zope.browsermenu.metaconfigure import (
+    menuDirective,
+    menuItemDirective,
+    subMenuItemDirective,
+    MenuItemFactory,
+    menuItemsDirective,
+    _checkViewFor,
+    addMenuItem,
+)

Modified: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/meta.zcml
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/meta.zcml	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/meta.zcml	2009-08-24 14:45:16 UTC (rev 103154)
@@ -4,54 +4,10 @@
     xmlns:zcml="http://namespaces.zope.org/zcml">
 
   <include package="zope.browserresource" file="meta.zcml" />
+  <include package="zope.browsermenu" file="meta.zcml" />
 
   <meta:directives namespace="http://namespaces.zope.org/browser">
 
-    <!-- browser menus -->
-
-    <meta:directive
-        name="menu"
-        schema=".metadirectives.IMenuDirective"
-        handler=".menumeta.menuDirective"
-        />
-
-    <meta:complexDirective
-        name="menuItems"
-        schema=".metadirectives.IMenuItemsDirective"
-        handler=".menumeta.menuItemsDirective"
-        >
-
-      <meta:subdirective
-          name="menuItem"
-          schema=".metadirectives.IMenuItemSubdirective"
-          />
-
-      <meta:subdirective
-          name="subMenuItem"
-          schema=".metadirectives.ISubMenuItemSubdirective"
-          />
-
-    </meta:complexDirective>
-
-    <meta:directive
-        name="menuItem"
-        schema=".metadirectives.IMenuItemDirective"
-        handler=".menumeta.menuItemDirective"
-        />
-
-    <meta:directive
-        name="subMenuItem"
-        schema=".metadirectives.ISubMenuItemDirective"
-        handler=".menumeta.subMenuItemDirective"
-        />
-
-    <meta:directive
-        name="addMenuItem"
-        schema=".metadirectives.IAddMenuItemDirective"
-        handler=".menumeta.addMenuItem"
-        />
-
-
     <!-- browser views -->
 
     <meta:complexDirective

Modified: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/metadirectives.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/metadirectives.py	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/metadirectives.py	2009-08-24 14:45:16 UTC (rev 103154)
@@ -24,7 +24,7 @@
 from zope.security.zcml import Permission
 
 from zope.component.zcml import IBasicViewInformation
-from zope.app.publisher.browser.fields import MenuField
+from zope.browsermenu.field import MenuField
 
 # BBB imports
 from zope.browserresource.metadirectives import (
@@ -32,8 +32,19 @@
     IResourceDirective,
     II18nResourceDirective,
     II18nResourceTranslationSubdirective,
-    IResourceDirectoryDirective
+    IResourceDirectoryDirective,
+    IIconDirective
 )
+from zope.browsermenu.metadirectives import (
+    IMenuDirective,
+    IMenuItemsDirective,
+    IMenuItem,
+    IMenuItemSubdirective,
+    IMenuItemDirective,
+    ISubMenuItemSubdirective,
+    ISubMenuItemDirective,
+    IAddMenuItemDirective,
+)
 
 #
 # browser views
@@ -226,226 +237,6 @@
     """
 
 #
-# browser menus
-#
-
-class IMenuDirective(Interface):
-    """Define a browser menu"""
-
-    id = TextLine(
-        title=u"The name of the menu.",
-        description=u"This is, effectively, an id.",
-        required=False
-        )
-
-    title = MessageID(
-        title=u"Title",
-        description=u"A descriptive title for documentation purposes",
-        required=False
-        )
-    
-    description = MessageID(
-        title=u"Description",
-        description=u"A description title of the menu.",
-        required=False
-        )
-
-    class_ = GlobalObject(
-        title=u"Menu Class",
-        description=u"The menu class used to generate the menu.",
-        required=False
-        )
-
-    interface = GlobalInterface(
-        title=u"The menu's interface.",
-        required=False
-        )
-    
-
-class IMenuItemsDirective(Interface):
-    """
-    Define a group of browser menu items
-
-    This directive is useful when many menu items are defined for the
-    same interface and menu.
-    """
-
-    menu = MenuField(
-        title=u"Menu name",
-        description=u"The (name of the) menu the items are defined for",
-        required=True,
-        )
-
-    for_ = GlobalObject(
-        title=u"Interface",
-        description=u"The interface the menu items are defined for",
-        required=True
-        )
-
-    layer = GlobalInterface(
-        title=u"Layer",
-        description=u"The Layer for which the item is declared.",
-        required=False
-        )
-
-    permission = Permission(
-        title=u"The permission needed access the item",
-        description=u"""
-        This can usually be inferred by the system, however, doing so
-        may be expensive. When displaying a menu, the system tries to
-        traverse to the URLs given in each action to determine whether
-        the url is accessible to the current user. This can be
-        avoided if the permission is given explicitly.""",
-        required=False
-        )
-
-
-class IMenuItem(Interface):
-    """Common menu item configuration
-    """
-
-    title = MessageID(
-        title=u"Title",
-        description=u"The text to be displayed for the menu item",
-        required=True
-        )
-
-    description = MessageID(
-        title=u"A longer explanation of the menu item",
-        description=u"""
-        A UI may display this with the item or display it when the
-        user requests more assistance.""",
-        required=False
-        )
-
-    icon = TextLine(
-        title=u"Icon Path",
-        description=u"Path to the icon resource representing this menu item.",
-        required=False
-        )
-
-    permission = Permission(
-        title=u"The permission needed access the item",
-        description=u"""
-        This can usually be inferred by the system, however, doing so
-        may be expensive. When displaying a menu, the system tries to
-        traverse to the URLs given in each action to determine whether
-        the url is accessible to the current user. This can be
-        avoided if the permission is given explicitly.""",
-        required=False
-        )
-
-    filter = TextLine(
-        title=u"A condition for displaying the menu item",
-        description=u"""
-        The condition is given as a TALES expression. The expression
-        has access to the variables:
-
-        context -- The object the menu is being displayed for
-
-        request -- The browser request
-
-        nothing -- None
-
-        The menu item will not be displayed if there is a filter and
-        the filter evaluates to a false value.""",
-        required=False
-        )
-
-    order = Int(
-        title=u"Order",
-        description=u"A relative position of the menu item in the menu.",
-        required=False,
-        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"""
-
-    action = TextLine(
-        title=u"The relative url to use if the item is selected",
-        description=u"""
-        The url is relative to the object the menu is being displayed
-        for.""",
-        required=True
-        )
-
-class IMenuItemDirective(IMenuItemsDirective, IMenuItemSubdirective):
-    """Define one menu item"""
-
-class ISubMenuItemSubdirective(IMenuItem):
-    """Define a menu item that represents a a sub menu.
-
-    For a sub-menu menu item, the action is optional, this the item itself
-    might not represent a destination, but just an entry point to the sub menu. 
-    """
-
-    action = TextLine(
-        title=u"The relative url to use if the item is selected",
-        description=u"""
-        The url is relative to the object the menu is being displayed
-        for.""",
-        required=False
-        )
-
-    submenu = TextLine(
-        title=u"Sub-Menu Id",
-        description=u"The menu that will be used to provide the sub-entries.",
-        required=True,
-        )
-    
-class ISubMenuItemDirective(IMenuItemsDirective, ISubMenuItemSubdirective):
-    """Define one menu item"""
-
-class IAddMenuItemDirective(IMenuItem):
-    """Define an add-menu item"""
-
-    for_ = GlobalInterface(
-        title=u"Interface",
-        description=u"The interface the menu items are defined for",
-        required=False
-        )
-
-    class_ = GlobalObject(
-        title=u"Class",
-        description=u"""
-        A class to be used as a factory for creating new objects""",
-        required=False
-        )
-
-    factory = Id(
-        title=u"Factory",
-        description=u"A factory id for creating new objects",
-        required = False,
-        )
-
-    view = TextLine(
-        title=u"Custom view name",
-        description=u"The name of a custom add view",
-        required = False,
-        )
-
-    menu = MenuField(
-        title=u"Menu name",
-        description=u"The (name of the) menu the items are defined for",
-        required=False,
-        )
-
-    layer = GlobalInterface(
-        title=u"The layer the custom view is declared for",
-        description=u"The default layer for which the custom view is "
-                    u"applicable. By default it is applied to all layers.",
-        required=False
-        )
-
-#
 # misc. directives
 #
 
@@ -458,67 +249,3 @@
         description=u"Default skin name",
         required=True
         )
-
-
-class IIconDirective(Interface):
-    """
-    Define an icon for an interface
-    """
-
-    name = TextLine(
-        title=u"The name of the icon.",
-        description=u"The name shows up in URLs/paths. For example 'foo'.",
-        required=True
-        )
-
-    for_ = GlobalInterface(
-        title=u"The interface this icon is for.",
-        description=u"""
-        The icon will be for all objects that implement this
-        interface.""",
-        required=True
-        )
-
-    file = Path(
-        title=u"File",
-        description=u"The file containing the icon.",
-        required=False
-        )
-
-    resource = TextLine(
-        title=u"Resource",
-        description=u"A resource containing the icon.",
-        required=False
-        )
-
-    title = MessageID(
-        title=u"Title",
-        description=u"Descriptive title",
-        required=False
-        )
-
-    layer = GlobalInterface(
-        title=u"The layer the icon should be found in",
-        description=u"""
-        For information on layers, see the documentation for the skin
-        directive. Defaults to "default".""",
-        required=False
-        )
-
-    width = Int(
-        title=u"The width of the icon.",
-        description=u"""
-        The width will be used for the <img width="..." />
-        attribute. Defaults to 16.""",
-        required=False,
-        default=16
-        )
-    
-    height = Int(
-        title=u"The height of the icon.",
-        description=u"""
-        The height will be used for the <img height="..." />
-        attribute. Defaults to 16.""",
-        required=False,
-        default=16
-        )

Deleted: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/addmenuitems.zcml
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/addmenuitems.zcml	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/addmenuitems.zcml	2009-08-24 14:45:16 UTC (rev 103154)
@@ -1,22 +0,0 @@
-<configure
-    xmlns="http://namespaces.zope.org/zope"
-    xmlns:browser="http://namespaces.zope.org/browser"
-    i18n_domain="zope">
-
-  <browser:addform
-      schema=".tests.test_menudirectives.I1"
-      name="add2.html"
-      content_factory=".tests.test_menudirectives.C1"
-      permission="zope.Public"
-      layer="zope.app.publisher.browser.tests.test_addMenuItem.ILayerStub"
-      />
-
-  <browser:addMenuItem
-      class=".tests.test_menudirectives.I1"
-      title="Add menu Item"
-      view="add2.html"
-      permission="zope.Public" 
-      layer="zope.app.publisher.browser.tests.test_addMenuItem.ILayerStub"
-      />
-
-</configure>

Deleted: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/menus-permissions.zcml
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/menus-permissions.zcml	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/menus-permissions.zcml	2009-08-24 14:45:16 UTC (rev 103154)
@@ -1,19 +0,0 @@
-<configure
-    xmlns="http://namespaces.zope.org/zope"
-    xmlns:browser="http://namespaces.zope.org/browser"
-    i18n_domain="zope">
-
-  <permission id="zope.View" title="Test permission"/>
-
-  <browser:menu 
-      id="test_id" 
-      title="test menu" />
-
-  <browser:menuItems 
-      menu="test_id"
-      for=".tests.test_menudirectives.I2"
-      permission="zope.View">
-    <browser:menuItem action="b1" title="b1" />
-  </browser:menuItems>
-
-</configure>

Deleted: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/menus.zcml
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/menus.zcml	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/menus.zcml	2009-08-24 14:45:16 UTC (rev 103154)
@@ -1,63 +0,0 @@
-<configure
-    xmlns="http://namespaces.zope.org/zope"
-    xmlns:browser="http://namespaces.zope.org/browser"
-    i18n_domain="zope">
-
-  <browser:menu 
-      id="test_id" 
-      title="test menu" />
-
-  <browser:menu 
-      id="test_sub_id" 
-      title="test sub menu 2" />
-
-  <browser:menuItems 
-      menu="test_id" 
-      for="zope.interface.Interface">
-    <browser:menuItem action="a1" title="t1" />
-    <browser:subMenuItem submenu="test_sub_id" title="s1" />
-  </browser:menuItems>
-
-  <browser:menuItems 
-      menu="test_id"
-      for=".tests.test_menudirectives.I1">
-    <browser:menuItem action="a2" title="t2" />
-  </browser:menuItems>
-
-  <browser:menuItems 
-      menu="test_id"
-      for=".tests.test_menudirectives.I11">
-    <browser:menuItem action="a3" title="t3" filter="context" />
-    <browser:menuItem action="a4" title="t4" filter="not:context" />
-  </browser:menuItems>
-
-  <browser:menuItems 
-      menu="test_id"
-      for=".tests.test_menudirectives.I111">
-    <browser:menuItem action="a5" title="t5" />
-    <browser:menuItem action="a6" title="t6" />
-    <browser:menuItem action="f7" title="t7" />
-    <browser:menuItem action="u8" title="t8" />
-  </browser:menuItems>
-
-  <browser:menuItems 
-      menu="test_id"
-      for=".tests.test_menudirectives.I12">
-    <browser:menuItem action="a9" title="t9" />
-  </browser:menuItems>
-
-  <browser:menuItems 
-      menu="test_sub_id"
-      for=".tests.test_menudirectives.I111">
-    <browser:menuItem action="a10" title="t10" />
-  </browser:menuItems>
-
-  <browser:menuItems 
-      menu="test_id"
-      for=".tests.test_menudirectives.I111"
-      layer=".tests.test_menudirectives.IMyLayer">
-    <browser:menuItem action="a11" title="t11" />
-    <browser:subMenuItem submenu="test_sub_id" title="s2" />
-  </browser:menuItems>
-
-</configure>

Deleted: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/menutestlayer.zcml
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/menutestlayer.zcml	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/menutestlayer.zcml	2009-08-24 14:45:16 UTC (rev 103154)
@@ -1,22 +0,0 @@
-<configure
-  xmlns="http://namespaces.zope.org/zope"
-  xmlns:browser="http://namespaces.zope.org/browser"
-  i18n_domain="zope">
-
-  <include package="zope.app.publisher" file="meta.zcml" />
-
-  <browser:menu
-    id="test_menu"
-    title="Test Menu"
-    />
-
-  <browser:page
-    for="zope.interface.Interface"
-    name="foo"
-    class="zope.app.publisher.browser.tests.test_menutestlayer.View"
-    permission="zope.Public"
-    menu="test_menu" title="Foo"
-    />
-
-</configure>
-

Modified: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/support.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/support.py	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/support.py	2009-08-24 14:45:16 UTC (rev 103154)
@@ -23,7 +23,7 @@
 
 from zope.site.hooks import setSite
 
-from zope.app.publisher.browser.menu import BrowserMenu
+from zope.browsermenu.menu import BrowserMenu
 
 class Site:
 

Deleted: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_addMenuItem.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_addMenuItem.py	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_addMenuItem.py	2009-08-24 14:45:16 UTC (rev 103154)
@@ -1,428 +0,0 @@
-#############################################################################
-#
-# Copyright (c) 2003 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Test the addMenuItem directive
-
->>> context = Context()
->>> addMenuItem(context, class_=X, title="Add an X",
-...             permission="zope.ManageContent")
->>> context
-((('utility',
-   <InterfaceClass zope.component.interfaces.IFactory>,
-   'BrowserAdd__zope.app.publisher.browser.tests.test_addMenuItem.X'),
-  <function handler>,
-  ('registerUtility',
-   <Factory for <class 'zope.app.publisher.browser.tests.test_addMenuItem.X'>>,
-   <InterfaceClass zope.component.interfaces.IFactory>,
-   'BrowserAdd__zope.app.publisher.browser.tests.test_addMenuItem.X'),
-  {'factory': None}),
- (None,
-  <function provideInterface>,
-  ('zope.component.interfaces.IFactory',
-   <InterfaceClass zope.component.interfaces.IFactory>),
-  {}),
- (('adapter',
-   (<InterfaceClass zope.browser.interfaces.IAdding>,
-    <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-   <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>,
-   'Add an X'),
-  <function handler>,
-  ('registerAdapter',
-   <zope.app.publisher.browser.menumeta.MenuItemFactory object>,
-   (<InterfaceClass zope.browser.interfaces.IAdding>,
-    <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-   <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>,
-   'Add an X',
-   ''),
-  {}),
- (None,
-  <function provideInterface>,
-  ('',
-   <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>),
-  {}),
- (None,
-  <function provideInterface>,
-  ('', <InterfaceClass zope.browser.interfaces.IAdding>),
-  {}),
- (None,
-  <function provideInterface>,
-  ('',
-   <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-  {}))
-
-$Id$
-"""
-
-import unittest
-from zope.testing.doctest import DocTestSuite
-import re
-import pprint
-import cStringIO
-from zope.interface import Interface
-from zope.publisher.interfaces.browser import IBrowserRequest
-from zope.app.publisher.browser.menumeta import addMenuItem
-
-atre = re.compile(' at [0-9a-fA-Fx]+')
-
-class IX(Interface):
-    pass
-
-class X(object):
-    pass
-
-class ILayerStub(IBrowserRequest):
-    pass
-
-class MenuStub(object):
-    pass
-
-
-class Context(object):
-    actions = ()
-    info = ''
-
-    def action(self, discriminator, callable, args=(), kw={}, order=0):
-        self.actions += ((discriminator, callable, args, kw), )
-
-    def __repr__(self):
-        stream = cStringIO.StringIO()
-        pprinter = pprint.PrettyPrinter(stream=stream, width=60)
-        pprinter.pprint(self.actions)
-        r = stream.getvalue()
-        return (''.join(atre.split(r))).strip()
-
-
-def test_w_factory():
-    """
-    >>> context = Context()
-    >>> addMenuItem(context, factory="x.y.z", title="Add an X",
-    ...             permission="zope.ManageContent", description="blah blah",
-    ...             filter="context/foo")
-    >>> context
-    ((('adapter',
-       (<InterfaceClass zope.browser.interfaces.IAdding>,
-        <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>,
-       'Add an X'),
-      <function handler>,
-      ('registerAdapter',
-       <zope.app.publisher.browser.menumeta.MenuItemFactory object>,
-       (<InterfaceClass zope.browser.interfaces.IAdding>,
-        <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>,
-       'Add an X',
-       ''),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('',
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('', <InterfaceClass zope.browser.interfaces.IAdding>),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('',
-       <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-      {}))
-    """
-
-def test_w_factory_and_view():
-    """
-    >>> context = Context()
-    >>> addMenuItem(context, factory="x.y.z", title="Add an X",
-    ...             permission="zope.ManageContent", description="blah blah",
-    ...             filter="context/foo", view="AddX")
-    >>> context
-    ((None,
-      <function _checkViewFor>,
-      (<InterfaceClass zope.browser.interfaces.IAdding>,
-       <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>,
-       'AddX'),
-      {}),
-     (('adapter',
-       (<InterfaceClass zope.browser.interfaces.IAdding>,
-        <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>,
-       'Add an X'),
-      <function handler>,
-      ('registerAdapter',
-       <zope.app.publisher.browser.menumeta.MenuItemFactory object>,
-       (<InterfaceClass zope.browser.interfaces.IAdding>,
-        <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>,
-       'Add an X',
-       ''),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('',
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('', <InterfaceClass zope.browser.interfaces.IAdding>),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('',
-       <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-      {}))
-    """
-
-def test_w_factory_class_view():
-    """
-    >>> context = Context()
-    >>> addMenuItem(context, class_=X, title="Add an X",
-    ...             permission="zope.ManageContent", description="blah blah",
-    ...             filter="context/foo", view="AddX")
-    >>> import pprint
-    >>> context
-    ((('utility',
-       <InterfaceClass zope.component.interfaces.IFactory>,
-       'BrowserAdd__zope.app.publisher.browser.tests.test_addMenuItem.X'),
-      <function handler>,
-      ('registerUtility',
-       <Factory for <class 'zope.app.publisher.browser.tests.test_addMenuItem.X'>>,
-       <InterfaceClass zope.component.interfaces.IFactory>,
-       'BrowserAdd__zope.app.publisher.browser.tests.test_addMenuItem.X'),
-      {'factory': None}),
-     (None,
-      <function provideInterface>,
-      ('zope.component.interfaces.IFactory',
-       <InterfaceClass zope.component.interfaces.IFactory>),
-      {}),
-     (None,
-      <function _checkViewFor>,
-      (<InterfaceClass zope.browser.interfaces.IAdding>,
-       <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>,
-       'AddX'),
-      {}),
-     (('adapter',
-       (<InterfaceClass zope.browser.interfaces.IAdding>,
-        <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>,
-       'Add an X'),
-      <function handler>,
-      ('registerAdapter',
-       <zope.app.publisher.browser.menumeta.MenuItemFactory object>,
-       (<InterfaceClass zope.browser.interfaces.IAdding>,
-        <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>,
-       'Add an X',
-       ''),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('',
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('', <InterfaceClass zope.browser.interfaces.IAdding>),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('',
-       <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-      {}))
-    """
-
-def test_w_for_factory():
-    """
-    >>> context = Context()
-    >>> addMenuItem(context, for_=IX, factory="x.y.z", title="Add an X",
-    ...             permission="zope.ManageContent", description="blah blah",
-    ...             filter="context/foo")
-    >>> context
-    ((None,
-      <function provideInterface>,
-      ('',
-       <InterfaceClass zope.app.publisher.browser.tests.test_addMenuItem.IX>),
-      {}),
-     (('adapter',
-       (<InterfaceClass zope.app.publisher.browser.tests.test_addMenuItem.IX>,
-        <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>,
-       'Add an X'),
-      <function handler>,
-      ('registerAdapter',
-       <zope.app.publisher.browser.menumeta.MenuItemFactory object>,
-       (<InterfaceClass zope.app.publisher.browser.tests.test_addMenuItem.IX>,
-        <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>,
-       'Add an X',
-       ''),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('',
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('',
-       <InterfaceClass zope.app.publisher.browser.tests.test_addMenuItem.IX>),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('',
-       <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-      {}))
-    """
-
-def test_w_factory_layer():
-    """
-    >>> context = Context()
-    >>> addMenuItem(context, factory="x.y.z", title="Add an X", layer=ILayerStub,
-    ...             permission="zope.ManageContent", description="blah blah",
-    ...             filter="context/foo")
-    >>> context
-    ((('adapter',
-       (<InterfaceClass zope.browser.interfaces.IAdding>,
-        <InterfaceClass zope.app.publisher.browser.tests.test_addMenuItem.ILayerStub>),
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>,
-       'Add an X'),
-      <function handler>,
-      ('registerAdapter',
-       <zope.app.publisher.browser.menumeta.MenuItemFactory object>,
-       (<InterfaceClass zope.browser.interfaces.IAdding>,
-        <InterfaceClass zope.app.publisher.browser.tests.test_addMenuItem.ILayerStub>),
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>,
-       'Add an X',
-       ''),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('',
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('', <InterfaceClass zope.browser.interfaces.IAdding>),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('',
-       <InterfaceClass zope.app.publisher.browser.tests.test_addMenuItem.ILayerStub>),
-      {}))
-    """
-
-def test_w_for_menu_factory():
-    """
-    >>> context = Context()
-    >>> addMenuItem(context, for_=IX, menu=MenuStub, factory="x.y.z", title="Add an X",
-    ...             permission="zope.ManageContent", description="blah blah",
-    ...             filter="context/foo")
-    >>> context
-    ((None,
-      <function provideInterface>,
-      ('',
-       <InterfaceClass zope.app.publisher.browser.tests.test_addMenuItem.IX>),
-      {}),
-     (('adapter',
-       (<InterfaceClass zope.app.publisher.browser.tests.test_addMenuItem.IX>,
-        <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-       <class 'zope.app.publisher.browser.tests.test_addMenuItem.MenuStub'>,
-       'Add an X'),
-      <function handler>,
-      ('registerAdapter',
-       <zope.app.publisher.browser.menumeta.MenuItemFactory object>,
-       (<InterfaceClass zope.app.publisher.browser.tests.test_addMenuItem.IX>,
-        <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-       <class 'zope.app.publisher.browser.tests.test_addMenuItem.MenuStub'>,
-       'Add an X',
-       ''),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('',
-       <class 'zope.app.publisher.browser.tests.test_addMenuItem.MenuStub'>),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('',
-       <InterfaceClass zope.app.publisher.browser.tests.test_addMenuItem.IX>),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('',
-       <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-      {}))
-    """
-
-def test_w_factory_icon_extra_order():
-    """
-    >>> context = Context()
-    >>> addMenuItem(context, factory="x.y.z", title="Add an X",
-    ...             permission="zope.ManageContent", description="blah blah",
-    ...             filter="context/foo", icon=u'/@@/icon.png', extra='Extra',
-    ...             order=99)
-    >>> context
-    ((('adapter',
-       (<InterfaceClass zope.browser.interfaces.IAdding>,
-        <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>,
-       'Add an X'),
-      <function handler>,
-      ('registerAdapter',
-       <zope.app.publisher.browser.menumeta.MenuItemFactory object>,
-       (<InterfaceClass zope.browser.interfaces.IAdding>,
-        <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>,
-       'Add an X',
-       ''),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('',
-       <InterfaceClass zope.app.publisher.interfaces.browser.AddMenu>),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('', <InterfaceClass zope.browser.interfaces.IAdding>),
-      {}),
-     (None,
-      <function provideInterface>,
-      ('',
-       <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
-      {}))
-    """
-
-from zope.configuration.xmlconfig import XMLConfig
-
-import zope.app
-import zope.app.form.browser
-
-from zope.app.testing import placelesssetup
-
-class TestAddMenuItem(placelesssetup.PlacelessSetup, unittest.TestCase):
-
-    def setUp(self):
-        super(TestAddMenuItem, self).setUp()
-        XMLConfig('meta.zcml', zope.app.form.browser)()
-        XMLConfig('meta.zcml', zope.app.publisher.browser)()
-
-    def test_addMenuItemDirectives(self):
-        XMLConfig('tests/addmenuitems.zcml', zope.app.publisher.browser)()
-
-def test_suite():
-    return unittest.TestSuite((
-        DocTestSuite(),
-        unittest.makeSuite(TestAddMenuItem),
-        ))
-
-if __name__ == '__main__':
-    unittest.main()

Modified: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_directives.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_directives.py	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_directives.py	2009-08-24 14:45:16 UTC (rev 103154)
@@ -44,8 +44,8 @@
 from zope.component.testfiles.views import IC, V1, VZMI, R1, IV
 from zope.app.publisher.browser.fileresource import FileResource
 from zope.app.publisher.browser.i18nfileresource import I18nFileResource
-from zope.app.publisher.browser.menu import getFirstMenuItem
-from zope.app.publisher.interfaces.browser import IMenuItemType, IBrowserMenu
+from zope.browsermenu.menu import getFirstMenuItem
+from zope.browsermenu.interfaces import IMenuItemType, IBrowserMenu
 from zope.app.testing import placelesssetup, ztapi
 
 tests_path = os.path.join(
@@ -1110,33 +1110,7 @@
 
         self.assert_(isinstance(v, V1))
 
-    def testMenuItemNeedsFor(self):
-        # <browser:menuItem> directive fails if no 'for' argument was provided
-        from zope.configuration.exceptions import ConfigurationError
-        self.assertRaises(ConfigurationError, xmlconfig, StringIO(template %
-            '''
-            <browser:menu
-                id="test_menu" title="Test menu" />
-            <browser:menuItem
-                title="Test Entry"
-                menu="test_menu"
-                action="@@test"
-            />
-            '''
-            ))
 
-	# it works, when the argument is there and a valid interface
-	xmlconfig(StringIO(template %
-            '''
-            <browser:menuItem
-                for="zope.component.testfiles.views.IC"
-                title="Test Entry"
-                menu="test_menu"
-               action="@@test"
-            />
-            '''
-            ))
-
 def test_suite():
     return unittest.TestSuite((
         unittest.makeSuite(Test),

Deleted: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_fields.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_fields.py	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_fields.py	2009-08-24 14:45:16 UTC (rev 103154)
@@ -1,30 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Test fields.
-
-$Id$
-"""
-import unittest
-from zope.testing.doctestunit import DocTestSuite
-from zope.app.testing import placelesssetup
-
-def test_suite():
-    return unittest.TestSuite((
-        DocTestSuite('zope.app.publisher.browser.fields',
-                     setUp=placelesssetup.setUp,
-                     tearDown=placelesssetup.tearDown),
-        ))
-
-if __name__ == '__main__':
-    unittest.main(defaultTest='test_suite')

Deleted: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_menu.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_menu.py	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_menu.py	2009-08-24 14:45:16 UTC (rev 103154)
@@ -1,34 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Browser Menu Item Tests
-
-$Id$
-"""
-import unittest
-from zope.testing import doctest, doctestunit
-
-from zope.app.testing import placelesssetup
-
-
-def test_suite():
-    return unittest.TestSuite((
-        doctest.DocFileSuite('../menu.txt',
-                             setUp=placelesssetup.setUp,
-                             tearDown=placelesssetup.tearDown,
-                             globs={'pprint': doctestunit.pprint},
-                             optionflags=doctest.NORMALIZE_WHITESPACE),
-        ))
-
-if __name__ == '__main__':
-    unittest.main(default='test_suite')

Deleted: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_menudirectives.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_menudirectives.py	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_menudirectives.py	2009-08-24 14:45:16 UTC (rev 103154)
@@ -1,163 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Browser Menu Directives Tests
-
-$Id$
-"""
-import unittest
-
-from zope.configuration.xmlconfig import XMLConfig
-from zope.interface import Interface, implements
-from zope.publisher.browser import TestRequest
-from zope.publisher.interfaces.browser import IBrowserPublisher
-from zope.publisher.interfaces.browser import IDefaultBrowserLayer
-from zope.app.publisher.interfaces.browser import IBrowserMenu
-from zope.security.interfaces import Unauthorized, Forbidden
-import zope.component
-
-import zope.security
-
-from zope.app.testing.placelesssetup import PlacelessSetup
-
-import zope.app.publisher.browser
-
-
-template = """<configure
-   xmlns='http://namespaces.zope.org/zope'
-   xmlns:browser='http://namespaces.zope.org/browser'
-   i18n_domain='zope'>
-   %s
-   </configure>"""
-
-class I1(Interface): pass
-class I11(I1): pass
-class I12(I1): pass
-class I111(I11): pass
-
-
-class C1(object):
-    implements(I1)
-
-class I2(Interface): pass
-
-class C2(object):
-    implements(I2)
-
-class TestObject(object):
-    implements(IBrowserPublisher, I111)
-
-    def f(self):
-        pass
-
-    def browserDefault(self, r):
-        return self, ()
-
-    def publishTraverse(self, request, name):
-        if name[:1] == 'f':
-            raise Forbidden(name)
-        if name[:1] == 'u':
-            raise Unauthorized(name)
-        return self.f
-
-class IMyLayer(Interface):
-    pass
-
-class IMySkin(IMyLayer, IDefaultBrowserLayer):
-    pass
-
-
-class TestPermissions(PlacelessSetup, unittest.TestCase):
-
-    def setUp(self):
-        super(TestPermissions, self).setUp()
-        XMLConfig('meta.zcml', zope.app.publisher.browser)()
-        XMLConfig('meta.zcml', zope.security)()
-
-    def testMenuItemsPermission(self):
-        XMLConfig('tests/menus-permissions.zcml', zope.app.publisher.browser)()
-
-        menu = zope.component.getUtility(IBrowserMenu, 'test_id')
-        # This is a bit icky, but the menu hides too much stuff from us.
-        items = zope.component.getAdapters((C2(), TestRequest()),
-                                           menu.getMenuItemType())
-        item = list(items)[0][1]
-        self.assertEquals("zope.View", item.permission)
-
-
-class Test(PlacelessSetup, unittest.TestCase):
-
-    def setUp(self):
-        super(Test, self).setUp()
-        XMLConfig('meta.zcml', zope.app.publisher.browser)()
-
-    def testMenusAndMenuItems(self):
-        XMLConfig('tests/menus.zcml', zope.app.publisher.browser)()
-
-        menu = zope.app.publisher.browser.menu.getMenu(
-            'test_id', TestObject(), TestRequest())
-
-        def d(n):
-            return {'action': "a%s" % n,
-                    'title':  "t%s" % n,
-                    'description': u'',
-                    'selected': '',
-                    'submenu': None,
-                    'icon': None,
-                    'extra': None}
-
-        self.assertEqual(menu[:-1], [d(5), d(6), d(3), d(2), d(1)])
-        self.assertEqual(
-            menu[-1],
-            {'submenu': [{'submenu': None,
-                          'description': u'',
-                          'extra': None,
-                          'selected': u'',
-                          'action': u'a10',
-                          'title': u't10',
-                          'icon': None}],
-             'description': u'',
-             'extra': None,
-             'selected': u'',
-             'action': u'',
-             'title': u's1',
-             'icon': None})
-
-        first = zope.app.publisher.browser.menu.getFirstMenuItem(
-            'test_id', TestObject(), TestRequest())
-
-        self.assertEqual(first, d(5))
-
-    def testMenuItemWithLayer(self):
-        XMLConfig('tests/menus.zcml', zope.app.publisher.browser)()
-
-        menu = zope.app.publisher.browser.menu.getMenu(
-            'test_id', TestObject(), TestRequest())
-        self.assertEqual(len(menu), 6)
-
-        menu = zope.app.publisher.browser.menu.getMenu(
-            'test_id', TestObject(), TestRequest(skin=IMyLayer))
-        self.assertEqual(len(menu), 2)
-
-        menu = zope.app.publisher.browser.menu.getMenu(
-            'test_id', TestObject(), TestRequest(skin=IMySkin))
-        self.assertEqual(len(menu), 8)
-
-def test_suite():
-    return unittest.TestSuite((
-        unittest.makeSuite(Test),
-        unittest.makeSuite(TestPermissions),
-        ))
-
-if __name__=='__main__':
-    unittest.main(defaultTest='test_suite')

Deleted: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_menutestlayer.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_menutestlayer.py	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_menutestlayer.py	2009-08-24 14:45:16 UTC (rev 103154)
@@ -1,61 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2008 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Test that menu items are re-registered in subsequent layers.
-
-Menu items registered with <browser:page/> were not re-registered after the
-first functional test layer ran. In any subsequent functional test layer the
-items where not availabe (introduced in 3.5.0a3)
-
-"""
-
-import os.path
-import unittest
-import zope.app.testing.functional
-import zope.publisher.browser
-import zope.publisher.interfaces.browser
-
-
-layer1 = zope.app.testing.functional.ZCMLLayer(
-    os.path.join(os.path.dirname(__file__), 'menutestlayer.zcml'),
-    __name__, 'MenuTestLayer1', allow_teardown=True)
-layer2 = zope.app.testing.functional.ZCMLLayer(
-    os.path.join(os.path.dirname(__file__), 'menutestlayer.zcml'),
-    __name__, 'MenuTestLayer2', allow_teardown=True)
-
-
-class View(object):
-    pass
-
-
-class TestLayerMenuReuse1(zope.app.testing.functional.BrowserTestCase):
-
-    layer = layer1
-
-    def test_menu(self):
-        request = zope.publisher.browser.TestRequest()
-        item = zope.app.publisher.browser.menu.getFirstMenuItem(
-            'test_menu', object(), request)
-        self.assertNotEqual(None, item)
-
-class TestLayerMenuReuse2(TestLayerMenuReuse1):
-
-    layer = layer2
-
-
-def test_suite():
-    suite = unittest.TestSuite()
-    suite.addTest(unittest.makeSuite(TestLayerMenuReuse1))
-    suite.addTest(unittest.makeSuite(TestLayerMenuReuse2))
-    return suite
-

Modified: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/viewmeta.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/viewmeta.py	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/viewmeta.py	2009-08-24 14:45:16 UTC (rev 103154)
@@ -31,7 +31,7 @@
 
 from zope.app.pagetemplate.simpleviewclass import SimpleViewClass
 from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
-from zope.app.publisher.browser.menumeta import menuItemDirective
+from zope.browsermenu.metaconfigure import menuItemDirective
 
 # There are three cases we want to suport:
 #

Modified: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/interfaces/browser.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/interfaces/browser.py	2009-08-24 14:36:26 UTC (rev 103153)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/interfaces/browser.py	2009-08-24 14:45:16 UTC (rev 103154)
@@ -15,147 +15,13 @@
 
 $Id$
 """
-from zope.app.publisher.i18n import ZopeMessageFactory as _
-from zope.interface import Interface, directlyProvides
-from zope.interface.interfaces import IInterface
-from zope.schema import TextLine, Text, URI, Int
 
-
-class IMenuItemType(IInterface):
-    """Menu item type
-
-    Menu item types are interfaces that define classes of
-    menu items.
-    """
-
-class AddMenu(Interface):
-    """Special menu for providing a list of addable objects."""
-
-directlyProvides(AddMenu, IMenuItemType)
-
-
-class IBrowserMenu(Interface):
-    """Menu
-
-    Menus are objects that can return a list of menu items they contain. How
-    they generate this list is up to them. Commonly, however, they will look
-    up adapters that provide the ``IBrowserMenuItem`` interface.
-    """
-
-    id = TextLine(
-        title=_("Menu Id"),
-        description=_("The id uniquely identifies this menu."),
-        required=True
-        )
-
-    title = TextLine(
-        title=_("Menu title"),
-        description=_("The title provides the basic label for the menu."),
-        required=False
-        )
-
-    description = Text(
-        title=_("Menu description"),
-        description=_("A description of the menu. This might be shown "
-                      "on menu pages or in pop-up help for menus."),
-        required=False
-        )
-
-    def getMenuItems(object, request):
-        """Return a TAL-friendly list of menu items.
-
-        The object (acts like the context) and request can be used to select
-        the items that are available.
-        """
-
-
-class IBrowserMenuItem(Interface):
-    """Menu type
-
-    An interface that defines a menu.
-    """
-
-    title = TextLine(
-        title=_("Menu item title"),
-        description=_("The title provides the basic label for the menu item."),
-        required=True
-        )
-
-    description = Text(
-        title=_("Menu item description"),
-        description=_("A description of the menu item. This might be shown "
-                      "on menu pages or in pop-up help for menu items."),
-        required=False
-        )
-
-    action = TextLine(
-        title=_("The URL to display if the item is selected"),
-        description=_("When a user selects a browser menu item, the URL"
-                      "given in the action is displayed. The action is "
-                      "usually given as a relative URL, relative to the "
-                      "object the menu item is for."),
-       required=True
-       )
-
-    order = Int(
-        title=_("Menu item ordering hint"),
-        description=_("This attribute provides a hint for menu item ordering."
-                      "Menu items will generally be sorted by the `for_`"
-                      "attribute and then by the order.")
-        )
-
-    filter_string = TextLine(
-        title=_("A condition for displaying the menu item"),
-        description=_("The condition is given as a TALES expression. The "
-                      "expression has access to the variables:\n"
-                      "\n"
-                      "context -- The object the menu is being displayed "
-                      "for\n"
-                      "\n"
-                      "request -- The browser request\n"
-                      "\n"
-                      "nothing -- None\n"
-                      "\n"
-                      "The menu item will not be displayed if there is a \n"
-                      "filter and the filter evaluates to a false value."),
-        required=False)
-
-    icon = URI(
-        title=_("Icon URI"),
-        description=_("URI of the icon representing this menu item"))
-       
-    def available():
-        """Test whether the menu item should be displayed
-        
-        A menu item might not be available for an object, for example
-        due to security limitations or constraints.
-        """
-
-class IBrowserSubMenuItem(IBrowserMenuItem):
-    """A menu item that points to a sub-menu."""
-
-    submenuId = TextLine(
-        title=_("Sub-Menu Id"),
-        description=_("The menu id of the menu that describes the "
-                      "sub-menu below this item."),
-        required=True)
-        
-    action = TextLine(
-        title=_("The URL to display if the item is selected"),
-        description=_("When a user selects a browser menu item, the URL "
-                      "given in the action is displayed. The action is "
-                      "usually given as a relative URL, relative to the "
-                      "object the menu item is for."),
-       required=False
-       )
-
-
-class IMenuAccessView(Interface):
-    """View that provides access to menus"""
-
-    def __getitem__(menu_id):
-        """Get menu information
-
-        Return a sequence of dictionaries with labels and
-        actions, where actions are relative URLs.
-        """
+# BBB imports
+from zope.browsermenu.interfaces import (
+    IMenuItemType,
+    AddMenu,
+    IBrowserMenu,
+    IBrowserMenuItem,
+    IBrowserSubMenuItem,
+    IMenuAccessView
+)



More information about the Checkins mailing list