[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