[Checkins] SVN: megrok.menu/branches/fixes-for-grok0.14/src/megrok/menu/ Add the base class megrok.menu.SubMenuItem and it's grokker SubMenuItemGrokker.
Santiago Videla
santiago.videla at gmail.com
Sat Dec 13 10:17:10 EST 2008
Log message for revision 94029:
Add the base class megrok.menu.SubMenuItem and it's grokker SubMenuItemGrokker.
With this class, now we can define sub-menus items in a Menu
Tests are added for this new functionality.
Because of grokker's priority, we can't define more than 1 level of sub-menus by now.
Menu :
- SubMenuLevel1 :
- SubMenuLevel2 :
- Item1
- Item2
It's not possible.
But you are able to do something like
Menu :
- SubMenuLevel1 :
- Item1
- Item2
- MenuItem
Changed:
U megrok.menu/branches/fixes-for-grok0.14/src/megrok/menu/__init__.py
U megrok.menu/branches/fixes-for-grok0.14/src/megrok/menu/component.py
U megrok.menu/branches/fixes-for-grok0.14/src/megrok/menu/grokker.py
U megrok.menu/branches/fixes-for-grok0.14/src/megrok/menu/tests/test_functional.py
-=-
Modified: megrok.menu/branches/fixes-for-grok0.14/src/megrok/menu/__init__.py
===================================================================
--- megrok.menu/branches/fixes-for-grok0.14/src/megrok/menu/__init__.py 2008-12-13 15:15:57 UTC (rev 94028)
+++ megrok.menu/branches/fixes-for-grok0.14/src/megrok/menu/__init__.py 2008-12-13 15:17:09 UTC (rev 94029)
@@ -1,4 +1,4 @@
-from megrok.menu.component import menuitem, Menu
+from megrok.menu.component import menuitem, Menu, SubMenuItem
# Provide these directives here as well:
from grokcore.component import name, title, description
Modified: megrok.menu/branches/fixes-for-grok0.14/src/megrok/menu/component.py
===================================================================
--- megrok.menu/branches/fixes-for-grok0.14/src/megrok/menu/component.py 2008-12-13 15:15:57 UTC (rev 94028)
+++ megrok.menu/branches/fixes-for-grok0.14/src/megrok/menu/component.py 2008-12-13 15:17:09 UTC (rev 94029)
@@ -6,6 +6,10 @@
class Menu(BrowserMenu):
pass
+class SubMenuItem(BrowserMenu):
+ pass
+
+
class menuitem(martian.Directive):
scope = martian.CLASS
store = martian.ONCE
@@ -18,3 +22,4 @@
"You can only pass unicode, ASCII, or a subclass "
"of megrok.menu.Menu to the '%s' directive." % self.name)
return (menu, icon, filter, order)
+
Modified: megrok.menu/branches/fixes-for-grok0.14/src/megrok/menu/grokker.py
===================================================================
--- megrok.menu/branches/fixes-for-grok0.14/src/megrok/menu/grokker.py 2008-12-13 15:15:57 UTC (rev 94028)
+++ megrok.menu/branches/fixes-for-grok0.14/src/megrok/menu/grokker.py 2008-12-13 15:17:09 UTC (rev 94029)
@@ -3,11 +3,14 @@
import grokcore.component
import grokcore.view
+import grokcore.security
from grokcore.security.util import protect_getattr
from grokcore.view.meta.views import ViewSecurityGrokker, default_view_name
from zope.configuration.exceptions import ConfigurationError
-from zope.app.publisher.browser.menumeta import menuDirective, menuItemDirective
+from zope.app.publisher.browser.menumeta import menuDirective, \
+ menuItemDirective, subMenuItemDirective
+
from zope.publisher.interfaces.browser import IDefaultBrowserLayer
from zope.publisher.interfaces.browser import IBrowserPage
@@ -25,6 +28,54 @@
title=title, description=description)
return True
+class SubMenuItemGrokker(martian.ClassGrokker):
+ martian.component(megrok.menu.SubMenuItem)
+
+ # We want to do this after MenuGrokker.
+ martian.priority(1000)
+
+ martian.directive(grokcore.component.name, get_default=default_view_name)
+ martian.directive(grokcore.component.title, default=u'')
+ martian.directive(grokcore.component.description, default=u'')
+ martian.directive(grokcore.component.context)
+ martian.directive(grokcore.view.layer, default=IDefaultBrowserLayer)
+ martian.directive(grokcore.security.require, name='permission')
+
+ martian.directive(megrok.menu.menuitem)
+
+ def execute(self, factory, config, name, title, description, \
+ menuitem=None, context=None, layer=None, permission=None):
+
+ menuDirective(config, id=name, class_=factory,
+ title=title, description=description)
+
+ if menuitem is None:
+ return False
+
+ menu_id, icon, filter, order = menuitem
+ try:
+ menu = config.resolve('zope.app.menus.'+menu_id)
+ except ConfigurationError, v:
+ raise GrokError("The %r menu could not be found. Please use "
+ "megrok.menu.Menu to register a menu first."
+ % menu_id, factory)
+
+ subMenuItemDirective(config, menu=menu, for_=context, submenu=name,
+ title=title, description=description, icon=icon,
+ filter=filter, permission=permission, layer=layer,
+ order=order, action='')
+
+ for method_name in IBrowserPage:
+ if method_name == '__call__':
+ continue
+ config.action(
+ discriminator=('protectMenuName', factory, method_name),
+ callable=protect_getattr,
+ args=(factory, method_name, permission),
+ )
+
+ return True
+
class MenuItemGrokker(ViewSecurityGrokker):
martian.directive(megrok.menu.menuitem)
martian.directive(grokcore.component.context)
Modified: megrok.menu/branches/fixes-for-grok0.14/src/megrok/menu/tests/test_functional.py
===================================================================
--- megrok.menu/branches/fixes-for-grok0.14/src/megrok/menu/tests/test_functional.py 2008-12-13 15:15:57 UTC (rev 94028)
+++ megrok.menu/branches/fixes-for-grok0.14/src/megrok/menu/tests/test_functional.py 2008-12-13 15:17:09 UTC (rev 94029)
@@ -11,7 +11,20 @@
>>> from zope.testbrowser.testing import Browser
>>> browser = Browser('http://localhost/manfred/showmenu')
>>> print browser.contents
- [{'action': 'edit',
+ [{'action': '',
+ 'description': '',
+ 'extra': None,
+ 'icon': None,
+ 'selected': u'',
+ 'submenu': [{'action': 'optionone',
+ 'description': u'',
+ 'extra': None,
+ 'icon': None,
+ 'selected': u'',
+ 'submenu': None,
+ 'title': 'Option one'}],
+ 'title': 'Options'},
+ {'action': 'edit',
'description': u'',
'extra': None,
'icon': None,
@@ -31,7 +44,33 @@
>>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
>>> browser.open('http://localhost/manfred/showmenu')
>>> print browser.contents
- [{'action': 'edit',
+ [{'action': '',
+ 'description': '',
+ 'extra': None,
+ 'icon': None,
+ 'selected': u'',
+ 'submenu': [{'action': 'optionone',
+ 'description': u'',
+ 'extra': None,
+ 'icon': None,
+ 'selected': u'',
+ 'submenu': None,
+ 'title': 'Option one'}],
+ 'title': 'Options'},
+ {'action': '',
+ 'description': '',
+ 'extra': None,
+ 'icon': None,
+ 'selected': u'',
+ 'submenu': [{'action': 'configoption',
+ 'description': u'',
+ 'extra': None,
+ 'icon': None,
+ 'selected': u'',
+ 'submenu': None,
+ 'title': 'Protected configuration'}],
+ 'title': 'Setup'},
+ {'action': 'edit',
'description': u'',
'extra': None,
'icon': None,
@@ -86,6 +125,21 @@
def render(self):
return 'edit'
+# also you can define sub-menus items
+class Options(megrok.menu.SubMenuItem):
+ grok.name('options')
+ grok.title('Options')
+ grok.description('')
+
+ megrok.menu.menuitem('actions')
+
+class OptionOne(grok.View):
+ grok.title('Option one')
+ megrok.menu.menuitem('options')
+
+ def render(self):
+ return 'option one'
+
# Here's a view that's protected by a permission. We expect the menu
# item that we configure for it to have the same permission setting:
@@ -100,6 +154,22 @@
def render(self):
return 'manage'
+#Sub menus item are also available to be protected using a permission
+class Setup(megrok.menu.SubMenuItem):
+ grok.require(ManageStuff)
+ grok.name('setup')
+ grok.title('Setup')
+ grok.description('')
+
+ megrok.menu.menuitem('actions')
+
+class ConfigOption(grok.View):
+ grok.title('Protected configuration')
+ megrok.menu.menuitem('setup')
+
+ def render(self):
+ return 'Configuration'
+
class ShowMenu(grok.View):
def render(self):
More information about the Checkins
mailing list