[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