[Checkins] SVN: zope.browsermenu/tags/ Tag 3.9.0

Dan Korostelev nadako at gmail.com
Thu Aug 27 09:13:08 EDT 2009


Log message for revision 103267:
  Tag 3.9.0

Changed:
  A   zope.browsermenu/tags/
  A   zope.browsermenu/tags/3.9.0/
  U   zope.browsermenu/tags/3.9.0/CHANGES.txt
  D   zope.browsermenu/tags/3.9.0/setup.py
  A   zope.browsermenu/tags/3.9.0/setup.py
  D   zope.browsermenu/tags/3.9.0/src/zope/browsermenu/configure.zcml
  A   zope.browsermenu/tags/3.9.0/src/zope/browsermenu/configure.zcml
  D   zope.browsermenu/tags/3.9.0/src/zope/browsermenu/interfaces.py
  A   zope.browsermenu/tags/3.9.0/src/zope/browsermenu/interfaces.py
  D   zope.browsermenu/tags/3.9.0/src/zope/browsermenu/menu.py
  A   zope.browsermenu/tags/3.9.0/src/zope/browsermenu/menu.py
  D   zope.browsermenu/tags/3.9.0/src/zope/browsermenu/metadirectives.py
  A   zope.browsermenu/tags/3.9.0/src/zope/browsermenu/metadirectives.py

-=-
Modified: zope.browsermenu/tags/3.9.0/CHANGES.txt
===================================================================
--- zope.browsermenu/trunk/CHANGES.txt	2009-08-27 12:24:25 UTC (rev 103265)
+++ zope.browsermenu/tags/3.9.0/CHANGES.txt	2009-08-27 13:13:07 UTC (rev 103267)
@@ -2,7 +2,7 @@
 CHANGES
 =======
 
-3.9.0 (unreleased)
+3.9.0 (2009-08-27)
 ==================
 
 Initial release. This package was splitted off zope.app.publisher.

Deleted: zope.browsermenu/tags/3.9.0/setup.py
===================================================================
--- zope.browsermenu/trunk/setup.py	2009-08-27 12:24:25 UTC (rev 103265)
+++ zope.browsermenu/tags/3.9.0/setup.py	2009-08-27 13:13:07 UTC (rev 103267)
@@ -1,59 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 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.
-#
-##############################################################################
-"""zope.browsermenu setup
-"""
-from setuptools import setup, find_packages, Extension
-
-long_description = (open('README.txt').read() + '\n\n' +
-                    open('CHANGES.txt').read())
-
-setup(name='zope.browsermenu',
-      version = '3.9.0dev',
-      url='http://pypi.python.org/pypi/zope.browsermenu/',
-      author='Zope Corporation and Contributors',
-      author_email='zope-dev at zope.org',
-      classifiers = ['Environment :: Web Environment',
-                     'Intended Audience :: Developers',
-                     'License :: OSI Approved :: Zope Public License',
-                     'Programming Language :: Python',
-                     'Operating System :: OS Independent',
-                     'Topic :: Internet :: WWW/HTTP',
-                     'Framework :: Zope3',
-                     ],
-      description='Browser menu implementation for Zope 3.',
-      long_description=long_description,
-
-      packages=find_packages('src'),
-      package_dir={'': 'src'},
-
-      namespace_packages=['zope'],
-      include_package_data=True,
-      install_requires=['setuptools',
-                        'zope.component>=3.7.0',
-                        'zope.configuration',
-                        'zope.i18nmessageid',
-                        'zope.interface',
-                        'zope.pagetemplate>=3.5.0',
-                        'zope.publisher>=3.8.0',
-                        'zope.schema',
-                        'zope.security[untrustedpython]',
-                        'zope.traversing>3.7.0',
-                        'zope.browser',
-                        ],
-      extras_require={
-          'test': ['zope.testing'],
-          },
-
-      zip_safe = False,
-      )

Copied: zope.browsermenu/tags/3.9.0/setup.py (from rev 103266, zope.browsermenu/trunk/setup.py)
===================================================================
--- zope.browsermenu/tags/3.9.0/setup.py	                        (rev 0)
+++ zope.browsermenu/tags/3.9.0/setup.py	2009-08-27 13:13:07 UTC (rev 103267)
@@ -0,0 +1,59 @@
+##############################################################################
+#
+# Copyright (c) 2007 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.
+#
+##############################################################################
+"""zope.browsermenu setup
+"""
+from setuptools import setup, find_packages, Extension
+
+long_description = (open('README.txt').read() + '\n\n' +
+                    open('CHANGES.txt').read())
+
+setup(name='zope.browsermenu',
+      version = '3.9.0',
+      url='http://pypi.python.org/pypi/zope.browsermenu/',
+      author='Zope Corporation and Contributors',
+      author_email='zope-dev at zope.org',
+      classifiers = ['Environment :: Web Environment',
+                     'Intended Audience :: Developers',
+                     'License :: OSI Approved :: Zope Public License',
+                     'Programming Language :: Python',
+                     'Operating System :: OS Independent',
+                     'Topic :: Internet :: WWW/HTTP',
+                     'Framework :: Zope3',
+                     ],
+      description='Browser menu implementation for Zope 3.',
+      long_description=long_description,
+
+      packages=find_packages('src'),
+      package_dir={'': 'src'},
+
+      namespace_packages=['zope'],
+      include_package_data=True,
+      install_requires=['setuptools',
+                        'zope.browser',
+                        'zope.component>=3.7.0',
+                        'zope.configuration',
+                        'zope.i18nmessageid',
+                        'zope.interface',
+                        'zope.pagetemplate>=3.5.0',
+                        'zope.publisher>=3.8.0',
+                        'zope.schema',
+                        'zope.security[untrustedpython]',
+                        'zope.traversing>3.7.0',
+                        ],
+      extras_require={
+          'test': ['zope.testing'],
+          },
+
+      zip_safe = False,
+      )

Deleted: zope.browsermenu/tags/3.9.0/src/zope/browsermenu/configure.zcml
===================================================================
--- zope.browsermenu/trunk/src/zope/browsermenu/configure.zcml	2009-08-27 12:24:25 UTC (rev 103265)
+++ zope.browsermenu/tags/3.9.0/src/zope/browsermenu/configure.zcml	2009-08-27 13:13:07 UTC (rev 103267)
@@ -1,14 +0,0 @@
-<configure xmlns="http://namespaces.zope.org/zope">
-
-  <interface interface=".interfaces.IMenuItemType" />
-
-  <view
-      for="*"
-      type="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
-      name="view_get_menu"
-      factory=".menu.MenuAccessView"
-      allowed_interface=".interfaces.IMenuAccessView"
-      permission="zope.Public"
-      />
-
-</configure>

Copied: zope.browsermenu/tags/3.9.0/src/zope/browsermenu/configure.zcml (from rev 103266, zope.browsermenu/trunk/src/zope/browsermenu/configure.zcml)
===================================================================
--- zope.browsermenu/tags/3.9.0/src/zope/browsermenu/configure.zcml	                        (rev 0)
+++ zope.browsermenu/tags/3.9.0/src/zope/browsermenu/configure.zcml	2009-08-27 13:13:07 UTC (rev 103267)
@@ -0,0 +1,15 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <interface interface=".interfaces.IMenuItemType" />
+
+  <!-- A view for use in templates, like context/@@view_get_menu/zmi_views -->
+  <view
+      for="*"
+      type="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
+      name="view_get_menu"
+      factory=".menu.MenuAccessView"
+      allowed_interface=".interfaces.IMenuAccessView"
+      permission="zope.Public"
+      />
+
+</configure>

Deleted: zope.browsermenu/tags/3.9.0/src/zope/browsermenu/interfaces.py
===================================================================
--- zope.browsermenu/trunk/src/zope/browsermenu/interfaces.py	2009-08-27 12:24:25 UTC (rev 103265)
+++ zope.browsermenu/tags/3.9.0/src/zope/browsermenu/interfaces.py	2009-08-27 13:13:07 UTC (rev 103267)
@@ -1,161 +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-Specific Publisher interfaces
-
-$Id: browser.py 97455 2009-03-03 19:57:53Z nadako $
-"""
-from zope.i18nmessageid 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.
-        """

Copied: zope.browsermenu/tags/3.9.0/src/zope/browsermenu/interfaces.py (from rev 103266, zope.browsermenu/trunk/src/zope/browsermenu/interfaces.py)
===================================================================
--- zope.browsermenu/tags/3.9.0/src/zope/browsermenu/interfaces.py	                        (rev 0)
+++ zope.browsermenu/tags/3.9.0/src/zope/browsermenu/interfaces.py	2009-08-27 13:13:07 UTC (rev 103267)
@@ -0,0 +1,161 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Menu-specific interfaces
+
+$Id: browser.py 97455 2009-03-03 19:57:53Z nadako $
+"""
+from zope.i18nmessageid 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.
+        """

Deleted: zope.browsermenu/tags/3.9.0/src/zope/browsermenu/menu.py
===================================================================
--- zope.browsermenu/trunk/src/zope/browsermenu/menu.py	2009-08-27 12:24:25 UTC (rev 103265)
+++ zope.browsermenu/tags/3.9.0/src/zope/browsermenu/menu.py	2009-08-27 13:13:07 UTC (rev 103267)
@@ -1,199 +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.
-#
-##############################################################################
-"""Menu Registration code.
-
-$Id: menu.py 100372 2009-05-25 19:31:23Z tseaver $
-"""
-__docformat__ = "reStructuredText"
-import sys
-
-from zope.component import getAdapters, getUtility
-from zope.interface import Interface, implements, providedBy
-from zope.interface.interfaces import IInterface
-from zope.pagetemplate.engine import Engine
-from zope.publisher.browser import BrowserView
-from zope.security import canAccess, checkPermission
-from zope.security.interfaces import Forbidden, Unauthorized
-from zope.security.proxy import removeSecurityProxy
-from zope.traversing.publicationtraverse import PublicationTraverser
-
-from zope.browsermenu.interfaces import IBrowserMenu, IMenuItemType
-from zope.browsermenu.interfaces import IBrowserMenuItem, IBrowserSubMenuItem
-from zope.browsermenu.interfaces import IMenuAccessView
-
-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)
-
-    title = u''
-    description = u''
-    action = u''
-    extra = None
-    order = 0
-    permission = None
-    filter = None
-    icon = None
-    _for = Interface
-
-    def available(self):
-        # 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):
-        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)
-
-    submenuId = None
-
-    def selected(self):
-        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)

Copied: zope.browsermenu/tags/3.9.0/src/zope/browsermenu/menu.py (from rev 103266, zope.browsermenu/trunk/src/zope/browsermenu/menu.py)
===================================================================
--- zope.browsermenu/tags/3.9.0/src/zope/browsermenu/menu.py	                        (rev 0)
+++ zope.browsermenu/tags/3.9.0/src/zope/browsermenu/menu.py	2009-08-27 13:13:07 UTC (rev 103267)
@@ -0,0 +1,199 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Menu implementation code
+
+$Id: menu.py 100372 2009-05-25 19:31:23Z tseaver $
+"""
+__docformat__ = "reStructuredText"
+import sys
+
+from zope.component import getAdapters, getUtility
+from zope.interface import Interface, implements, providedBy
+from zope.interface.interfaces import IInterface
+from zope.pagetemplate.engine import Engine
+from zope.publisher.browser import BrowserView
+from zope.security import canAccess, checkPermission
+from zope.security.interfaces import Forbidden, Unauthorized
+from zope.security.proxy import removeSecurityProxy
+from zope.traversing.publicationtraverse import PublicationTraverser
+
+from zope.browsermenu.interfaces import IBrowserMenu, IMenuItemType
+from zope.browsermenu.interfaces import IBrowserMenuItem, IBrowserSubMenuItem
+from zope.browsermenu.interfaces import IMenuAccessView
+
+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)
+
+    title = u''
+    description = u''
+    action = u''
+    extra = None
+    order = 0
+    permission = None
+    filter = None
+    icon = None
+    _for = Interface
+
+    def available(self):
+        # 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):
+        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)
+
+    submenuId = None
+
+    def selected(self):
+        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)

Deleted: zope.browsermenu/tags/3.9.0/src/zope/browsermenu/metadirectives.py
===================================================================
--- zope.browsermenu/trunk/src/zope/browsermenu/metadirectives.py	2009-08-27 12:24:25 UTC (rev 103265)
+++ zope.browsermenu/tags/3.9.0/src/zope/browsermenu/metadirectives.py	2009-08-27 13:13:07 UTC (rev 103267)
@@ -1,244 +0,0 @@
-#############################################################################
-#
-# Copyright (c) 2001, 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 configuration code
-
-This module defines the schemas for browser directives.
-
-$Id: metadirectives.py 103143 2009-08-24 12:28:19Z nadako $
-"""
-from zope.interface import Interface
-from zope.configuration.fields import GlobalObject, GlobalInterface
-from zope.configuration.fields import Tokens, Path, PythonIdentifier, MessageID
-from zope.schema import TextLine, Id, Int, Bool
-from zope.security.zcml import Permission
-
-from zope.component.zcml import IBasicViewInformation
-from zope.browsermenu.field import MenuField
-
-
-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
-        )

Copied: zope.browsermenu/tags/3.9.0/src/zope/browsermenu/metadirectives.py (from rev 103266, zope.browsermenu/trunk/src/zope/browsermenu/metadirectives.py)
===================================================================
--- zope.browsermenu/tags/3.9.0/src/zope/browsermenu/metadirectives.py	                        (rev 0)
+++ zope.browsermenu/tags/3.9.0/src/zope/browsermenu/metadirectives.py	2009-08-27 13:13:07 UTC (rev 103267)
@@ -0,0 +1,242 @@
+#############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+"""Menu ZCML directives
+
+$Id: metadirectives.py 103143 2009-08-24 12:28:19Z nadako $
+"""
+from zope.interface import Interface
+from zope.configuration.fields import GlobalObject, GlobalInterface
+from zope.configuration.fields import Tokens, Path, PythonIdentifier, MessageID
+from zope.schema import TextLine, Id, Int, Bool
+from zope.security.zcml import Permission
+
+from zope.component.zcml import IBasicViewInformation
+from zope.browsermenu.field import MenuField
+
+
+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
+        )



More information about the Checkins mailing list