[Zope3-checkins] CVS: Zope3/src/zope/app/publisher/browser -
globalbrowsermenuservice.py:1.21.4.2
Stephan Richter
srichter at cosmos.phy.tufts.edu
Thu Aug 14 14:58:39 EDT 2003
Update of /cvs-repository/Zope3/src/zope/app/publisher/browser
In directory cvs.zope.org:/tmp/cvs-serv10819/app/publisher/browser
Modified Files:
Tag: dreamcatcher-ttwschema-branch
globalbrowsermenuservice.py
Log Message:
Checkpoint check-in for people following the branch:
Got Local Browser Menu Service to work. I used a similar model to the
interface service, where the service uses registered Browser Menu utilities
to get its menu entries.
There are also a bunch of policy-type decisions that come with local menus.
One is whether a local menu should overwrite or complement existing menus.
Currently I have an 'inherit' flag that can be set. If true, the local menu
will add to the existing entries, otherwise it will overwrite them. Note
that this does not solve all use cases, such as if you want to take over
just a few entries, but I called YAGNI on it (someone else can do it, if it
is necessary).
I added and extended interfaces for all of this to work. I tried really
hard to avoid rewriting the getMenu() methof for the local menu service
version and I think I got it. ;-)
I also have a nice Overview screen for the Local Menu Service, which shows
you all available menus.
To Do:
- Flesh out the interfaces and implement missing methods.
- Clean up the code.
- Fix tests.
- Write a bunch of new tests.
=== Zope3/src/zope/app/publisher/browser/globalbrowsermenuservice.py 1.21.4.1 => 1.21.4.2 ===
--- Zope3/src/zope/app/publisher/browser/globalbrowsermenuservice.py:1.21.4.1 Wed Aug 13 09:36:28 2003
+++ Zope3/src/zope/app/publisher/browser/globalbrowsermenuservice.py Thu Aug 14 13:58:05 2003
@@ -11,6 +11,10 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
+"""Global Browser Menu Service
+
+$Id$
+"""
from zope.interface import classProvides
from zope.exceptions import DuplicationError, Unauthorized, Forbidden
@@ -26,13 +30,15 @@
from zope.app.security.permission import checkPermission
from zope.app.component.metaconfigure import handler
-from zope.app.interfaces.publisher.browser import IBrowserMenuService
+from zope.app.interfaces.publisher.browser import \
+ IBrowserMenuService, IGlobalBrowserMenuService, IBrowserMenu
from zope.app.pagetemplate.engine import Engine
from zope.app.publication.browser import PublicationTraverser
class Menu(object):
- '''Browser menu
- '''
+ """Browser menu"""
+
+ implements(IBrowserMenu)
def __init__(self, title, description=u'', usage=u''):
self.title = title
@@ -40,16 +46,130 @@
self.usage = usage
self.registry = TypeRegistry()
+ def getMenuItems(self, object=None):
+ """See zope.app.interfaces.publisher.browser.IMenuItem"""
+ results = []
+ if object is None:
+ for items in self.registry._reg.values():
+ results += items
+ else:
+ for items in self.registry.getAllForObject(object):
+ results += items
+ return results
+
-class GlobalBrowserMenuService(object):
- """Global Browser Menu Service
- """
+class BaseBrowserMenuService(object):
+ """Global Browser Menu Service"""
implements(IBrowserMenuService)
def __init__(self):
self._registry = {}
+ def getAllMenuItems(self, menu_id, object):
+ return self._registry[menu_id].getMenuItems(object)
+
+ def getMenu(self, menu_id, object, request, max=999999):
+ traverser = PublicationTraverser()
+
+ result = []
+ seen = {}
+ sm = getSecurityManager()
+
+ # stuff for figuring out the selected view
+ request_url = request.getURL()
+
+ for items in self.getAllMenuItems(menu_id, object):
+ action, title, description, filter, permission = items
+
+ # Make sure we don't repeat a specification for a given title
+ if title in seen:
+ continue
+ seen[title] = 1
+
+ if filter is not None:
+
+ try:
+ include = filter(Engine.getContext(
+ context = object,
+ nothing = None,
+ request = request,
+ ))
+ except Unauthorized:
+ include = 0
+
+ if not include:
+ continue
+
+ if permission:
+ # If we have an explicit permission, check that we
+ # can access it.
+ if not sm.checkPermission(permission, object) and \
+ permission is not CheckerPublic:
+ continue
+
+ elif action:
+ # Otherwise, test access by attempting access
+ path = action
+ l = action.find('?')
+ if l >= 0:
+ path = action[:l]
+ try:
+ v = traverser.traverseRelativeURL(
+ request, object, path)
+ # XXX
+ # tickle the security proxy's checker
+ # we're assuming that view pages are callable
+ # this is a pretty sound assumption
+ v.__call__
+ except (Unauthorized, Forbidden):
+ continue # Skip unauthorized or forbidden
+
+ normalized_action = action
+ if action.startswith('@@'):
+ normalized_action = action[2:]
+
+ if request_url.endswith(action):
+ selected='selected'
+ elif request_url.endswith('/'+normalized_action):
+ selected='selected'
+ elif request_url.endswith('++view++'+normalized_action):
+ selected='selected'
+ else:
+ selected=''
+
+ result.append({
+ 'title': title,
+ 'description': description,
+ 'action': "%s" % action,
+ 'selected': selected
+ })
+
+ if len(result) >= max:
+ return result
+
+ return result
+
+ def getMenuUsage(self, menu_id):
+ return self._registry[menu_id].usage
+
+
+ def getFirstMenuItem(self, menu_id, object, request):
+ r = self.getMenu(menu_id, object, request, max=1)
+ if r:
+ return r[0]
+ return None
+
+
+class GlobalBrowserMenuService(BaseBrowserMenuService):
+ """Global Browser Menu Service that can be manipulated by adding new menus
+ and menu entries."""
+
+ implements(IGlobalBrowserMenuService)
+
+ def __init__(self):
+ self._registry = {}
+
_clear = __init__
def menu(self, menu_id, title, description=u'', usage=u''):
@@ -81,96 +201,6 @@
data.append((action, title, description, filter, permission))
registry.register(interface, data)
- def getMenu(self, menu_id, object, request, max=999999):
- registry = self._registry[menu_id].registry
- traverser = PublicationTraverser()
-
- result = []
- seen = {}
- sm = getSecurityManager()
-
- # stuff for figuring out the selected view
- request_url = request.getURL()
-
- for items in registry.getAllForObject(object):
- for action, title, description, filter, permission in items:
-
- # Make sure we don't repeat a specification for a given title
- if title in seen:
- continue
- seen[title] = 1
-
- if filter is not None:
-
- try:
- include = filter(Engine.getContext(
- context = object,
- nothing = None,
- request = request,
- ))
- except Unauthorized:
- include = 0
-
- if not include:
- continue
-
- if permission:
- # If we have an explicit permission, check that we
- # can access it.
- if not sm.checkPermission(permission, object):
- continue
-
- elif action:
- # Otherwise, test access by attempting access
- path = action
- l = action.find('?')
- if l >= 0:
- path = action[:l]
- try:
- v = traverser.traverseRelativeURL(
- request, object, path)
- # XXX
- # tickle the security proxy's checker
- # we're assuming that view pages are callable
- # this is a pretty sound assumption
- v.__call__
- except (Unauthorized, Forbidden):
- continue # Skip unauthorized or forbidden
-
- normalized_action = action
- if action.startswith('@@'):
- normalized_action = action[2:]
-
- if request_url.endswith(action):
- selected='selected'
- elif request_url.endswith('/'+normalized_action):
- selected='selected'
- elif request_url.endswith('++view++'+normalized_action):
- selected='selected'
- else:
- selected=''
-
- result.append({
- 'title': title,
- 'description': description,
- 'action': "%s" % action,
- 'selected': selected
- })
-
- if len(result) >= max:
- return result
-
- return result
-
- def getMenuUsage(self, menu_id):
- return self._registry[menu_id].usage
-
-
- def getFirstMenuItem(self, menu_id, object, request):
- r = self.getMenu(menu_id, object, request, max=1)
- if r:
- return r[0]
- return None
def menuDirective(_context, id, title, description='', usage=u''):
_context.action(
@@ -219,8 +249,3 @@
from zope.testing.cleanup import addCleanUp
addCleanUp(_clear)
del addCleanUp
-
-__doc__ = GlobalBrowserMenuService.__doc__ + """
-
-$Id$
-"""
More information about the Zope3-Checkins
mailing list