[Zope3-checkins] SVN: Zope3/trunk/ The browser:containerViews directive does now provide an optional layer attribute.

Dominik Huber dominik.huber at projekt01.ch
Tue Feb 8 13:16:50 EST 2005


Log message for revision 29085:
  The browser:containerViews directive does now provide an optional layer attribute.
  
  Partially fixed issue #306 (Problem 2: Browser page and view directive cannot register serveral pages views within different layers for the same for, menu and title attributes.)

Changed:
  U   Zope3/trunk/doc/CHANGES.txt
  U   Zope3/trunk/src/zope/app/container/browser/metaconfigure.py
  U   Zope3/trunk/src/zope/app/container/browser/tests/test_directive.py
  U   Zope3/trunk/src/zope/app/publisher/browser/tests/test_directives.py
  U   Zope3/trunk/src/zope/app/publisher/browser/viewmeta.py

-=-
Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt	2005-02-08 18:09:48 UTC (rev 29084)
+++ Zope3/trunk/doc/CHANGES.txt	2005-02-08 18:16:50 UTC (rev 29085)
@@ -10,6 +10,9 @@
 
     New features
 
+      - The browser:containerViews directive provides an optional layer
+        attribute.
+
       - Groups for unauthenticated users, authenticated users, and
         everybody can now be defined in ZCML.
 
@@ -324,6 +327,10 @@
 
     Bug Fixes
 
+      - Partially fixed issue #306 (Problem 2: Browser page and view directive
+        cannot register serveral pages views within different layers for
+        the same for, menu and title attributes.)
+
       - Fixed issue #353 (applySkin does not work in functional doctests).
 
       - Fixed issue #293 (SequenceWidget and CustomWidgetFactory).

Modified: Zope3/trunk/src/zope/app/container/browser/metaconfigure.py
===================================================================
--- Zope3/trunk/src/zope/app/container/browser/metaconfigure.py	2005-02-08 18:09:48 UTC (rev 29084)
+++ Zope3/trunk/src/zope/app/container/browser/metaconfigure.py	2005-02-08 18:16:50 UTC (rev 29085)
@@ -18,8 +18,10 @@
 
 __docformat__ = 'restructuredtext'
 
+from zope.app.component.fields import LayerField
 from zope.interface import Interface
 from zope.configuration.fields import GlobalInterface
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
 from zope.schema import Id
 from zope.app.publisher.browser.viewmeta import page, view
 from zope.app.container.browser.contents import Contents
@@ -51,8 +53,16 @@
         title=u"The permission needed for add page.",
         required=False)
 
+    layer = LayerField(
+        title=_("The layer the view is in."),
+        description=_("""A skin is composed of layers. It is common to put 
+        skin specific views in a layer named after the skin. If the 'layer'
+        attribute is not supplied, it defaults to 'default'."""),
+        required=False
+        )
 
-def containerViews(_context, for_, contents=None, add=None, index=None):
+
+def containerViews(_context, for_, contents=None, add=None, index=None, layer=IDefaultBrowserLayer):
     """Set up container views for a given content type."""
 
     if for_ is None:
@@ -61,16 +71,16 @@
     if contents is not None:
         from zope.app.menus import zmi_views
         page(_context, name='contents.html', permission=contents,
-             for_=for_, class_=Contents, attribute='contents',
+             for_=for_, layer=layer, class_=Contents, attribute='contents',
              menu=zmi_views, title=_('Contents'))
 
     if index is not None:
         page(_context, name='index.html', permission=index, for_=for_,
-             class_=Contents, attribute='index')
+             layer=layer, class_=Contents, attribute='index')
 
     if add is not None:
         from zope.app.menus import zmi_actions
-        viewObj = view(_context, name='+', menu=zmi_actions,
+        viewObj = view(_context, name='+', layer=layer, menu=zmi_actions,
                        title=_('Add'), for_=for_, permission=add,
                        class_=Adding)
         viewObj.page(_context, name='index.html', attribute='index')

Modified: Zope3/trunk/src/zope/app/container/browser/tests/test_directive.py
===================================================================
--- Zope3/trunk/src/zope/app/container/browser/tests/test_directive.py	2005-02-08 18:09:48 UTC (rev 29084)
+++ Zope3/trunk/src/zope/app/container/browser/tests/test_directive.py	2005-02-08 18:16:50 UTC (rev 29085)
@@ -21,6 +21,7 @@
 
 import unittest
 from zope.interface import Interface
+from zope.publisher.interfaces import ILayer
 from zope.testing.doctestunit import DocTestSuite
 from zope.app.container.browser.metaconfigure import containerViews
 
@@ -44,6 +45,11 @@
 class I(Interface):
     pass
 
+
+class ITestLayer(ILayer):
+    pass
+
+
 def test_containerViews():
     """
     >>> from zope.app.publisher.browser.menu import menus
@@ -165,7 +171,129 @@
        <class 'zope.app.publisher.browser.viewmeta.+'>,
        'info')))
     """
-       
+
+def test_containerViews_layer():
+    """
+    >>> from zope.app.publisher.browser.menu import menus
+    >>> from zope.interface.interface import InterfaceClass
+    >>> zmi_views = InterfaceClass('zmi_views', __module__='zope.app.menus')
+    >>> menus.zmi_views = zmi_views
+    >>> zmi_actions = InterfaceClass('zmi_actions', __module__='zope.app.menus')
+    >>> menus.zmi_actions = zmi_actions
+
+    >>> context = Context()
+    >>> containerViews(context, for_=I, contents='zope.ManageContent',
+    ...                add='zope.ManageContent', index='zope.View', layer=ITestLayer)
+    >>> context
+    ((('adapter',
+       (<InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+        <InterfaceClass zope.publisher.interfaces.browser.IBrowserRequest>),
+       <InterfaceClass zope.app.menus.zmi_views>,
+       u'Contents'),
+      <function handler>,
+      ('Adapters',
+       'register',
+       (<InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+        <InterfaceClass zope.publisher.interfaces.browser.IBrowserRequest>),
+       <InterfaceClass zope.app.menus.zmi_views>,
+       u'Contents',
+       <zope.app.publisher.browser.menu.MenuItemFactory object>,
+       '')),
+     (None,
+      <function provideInterface>,
+      ('', <InterfaceClass zope.app.menus.zmi_views>)),
+     (None,
+      <function provideInterface>,
+      ('',
+       <InterfaceClass zope.app.container.browser.tests.test_directive.I>)),
+     (None,
+      <function provideInterface>,
+      ('',
+       <InterfaceClass zope.publisher.interfaces.browser.IBrowserRequest>)),
+     (None,
+      <function provideInterface>,
+      ('',
+       <InterfaceClass zope.app.container.browser.tests.test_directive.I>)),
+     (('view',
+       <InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+       'contents.html',
+       <InterfaceClass zope.publisher.interfaces.browser.IBrowserRequest>,
+       <InterfaceClass zope.app.container.browser.tests.test_directive.ITestLayer>),
+      <function handler>,
+      ('Adapters',
+       'register',
+       (<InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+        <InterfaceClass zope.app.container.browser.tests.test_directive.ITestLayer>),
+       <InterfaceClass zope.interface.Interface>,
+       'contents.html',
+       <class 'zope.app.publisher.browser.viewmeta.Contents'>,
+       'info')),
+     (None,
+      <function provideInterface>,
+      ('',
+       <InterfaceClass zope.app.container.browser.tests.test_directive.I>)),
+     (('view',
+       <InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+       'index.html',
+       <InterfaceClass zope.publisher.interfaces.browser.IBrowserRequest>,
+       <InterfaceClass zope.app.container.browser.tests.test_directive.ITestLayer>),
+      <function handler>,
+      ('Adapters',
+       'register',
+       (<InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+        <InterfaceClass zope.app.container.browser.tests.test_directive.ITestLayer>),
+       <InterfaceClass zope.interface.Interface>,
+       'index.html',
+       <class 'zope.app.publisher.browser.viewmeta.Contents'>,
+       'info')),
+     (('adapter',
+       (<InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+        <InterfaceClass zope.publisher.interfaces.browser.IBrowserRequest>),
+       <InterfaceClass zope.app.menus.zmi_actions>,
+       u'Add'),
+      <function handler>,
+      ('Adapters',
+       'register',
+       (<InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+        <InterfaceClass zope.publisher.interfaces.browser.IBrowserRequest>),
+       <InterfaceClass zope.app.menus.zmi_actions>,
+       u'Add',
+       <zope.app.publisher.browser.menu.MenuItemFactory object>,
+       'info')),
+     (None,
+      <function provideInterface>,
+      ('', <InterfaceClass zope.app.menus.zmi_actions>)),
+     (None,
+      <function provideInterface>,
+      ('',
+       <InterfaceClass zope.app.container.browser.tests.test_directive.I>)),
+     (None,
+      <function provideInterface>,
+      ('',
+       <InterfaceClass zope.publisher.interfaces.browser.IBrowserRequest>)),
+     (None,
+      <function provideInterface>,
+      ('',
+       <InterfaceClass zope.app.container.browser.tests.test_directive.I>)),
+     (None,
+      <function provideInterface>,
+      ('', <InterfaceClass zope.interface.Interface>)),
+     (('view',
+       (<InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+        <InterfaceClass zope.app.container.browser.tests.test_directive.ITestLayer>),
+       '+',
+       <InterfaceClass zope.interface.Interface>),
+      <function handler>,
+      ('Adapters',
+       'register',
+       (<InterfaceClass zope.app.container.browser.tests.test_directive.I>,
+        <InterfaceClass zope.app.container.browser.tests.test_directive.ITestLayer>),
+       <InterfaceClass zope.interface.Interface>,
+       '+',
+       <class 'zope.app.publisher.browser.viewmeta.+'>,
+       'info')))
+    """
+
 def test_suite():
     return unittest.TestSuite((
         DocTestSuite(),

Modified: Zope3/trunk/src/zope/app/publisher/browser/tests/test_directives.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/tests/test_directives.py	2005-02-08 18:09:48 UTC (rev 29084)
+++ Zope3/trunk/src/zope/app/publisher/browser/tests/test_directives.py	2005-02-08 18:16:50 UTC (rev 29085)
@@ -26,6 +26,7 @@
 from zope.configuration.xmlconfig import xmlconfig, XMLConfig
 from zope.configuration.exceptions import ConfigurationError
 from zope.publisher.browser import TestRequest
+from zope.publisher.interfaces import ILayer
 from zope.publisher.interfaces.browser import IBrowserPublisher
 from zope.publisher.interfaces.browser import IBrowserRequest
 from zope.publisher.interfaces.browser import ISkin, IDefaultSkin
@@ -92,6 +93,17 @@
     def index(self):
         return self
 
+
+class ITestMenu(Interface):
+    """Test menu."""
+
+directlyProvides(ITestMenu, IMenuItemType)
+
+class ITestLayer(ILayer):
+    """Test Layer."""
+
+
+
 class Test(PlacelessSetup, unittest.TestCase):
 
     def setUp(self):
@@ -870,6 +882,43 @@
         v = zapi.getView(ob, 'index.html', request)
         self.assertEqual(v().strip(), '<html><body><p>test</p></body></html>')
 
+    def test_page_menu_within_different_layers(self):
+        path = os.path.join(tests_path, 'testfiles', 'test.pt')
+        self.assertEqual(zapi.queryView(ob, 'index.html', request),
+                         None)
+
+        xmlconfig(StringIO(template %
+            '''
+            <browser:menu
+                id="test_menu"
+                title="Test menu"
+                interface="zope.app.publisher.browser.tests.test_directives.ITestMenu"/>
+
+            <browser:layer 
+                name="test_layer"
+                interface="zope.app.publisher.browser.tests.test_directives.ITestLayer"
+                />
+
+            <browser:page
+                name="index.html"
+                permission="zope.Public"
+                for="zope.app.component.tests.views.IC"
+                template="%s"
+                menu="test_menu" title="Index"/>
+
+            <browser:page
+                name="index.html"
+                permission="zope.Public"
+                for="zope.app.component.tests.views.IC"
+                menu="test_menu" title="Index"
+                template="%s"
+                layer="zope.app.publisher.browser.tests.test_directives.ITestLayer"/>
+            ''' % (path, path)
+            ))
+
+        v = zapi.getView(ob, 'index.html', request)
+        self.assertEqual(v().strip(), '<html><body><p>test</p></body></html>')
+
     def testtemplateWClass(self):
         path = os.path.join(tests_path, 'testfiles', 'test2.pt')
 

Modified: Zope3/trunk/src/zope/app/publisher/browser/viewmeta.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/viewmeta.py	2005-02-08 18:09:48 UTC (rev 29084)
+++ Zope3/trunk/src/zope/app/publisher/browser/viewmeta.py	2005-02-08 18:16:50 UTC (rev 29085)
@@ -94,7 +94,7 @@
          attribute='__call__', menu=None, title=None, 
          ):
 
-    _handle_menu(_context, menu, title, [for_], name, permission)
+    _handle_menu(_context, menu, title, [for_], name, permission, layer)
     required = {}
 
     permission = _handle_permission(_context, permission)
@@ -212,7 +212,7 @@
                  menu=None, title=None, provides=Interface,
                  ):
 
-        _handle_menu(_context, menu, title, [for_], name, permission)
+        _handle_menu(_context, menu, title, [for_], name, permission, layer)
 
         permission = _handle_permission(_context, permission)
 
@@ -373,9 +373,12 @@
             callable = provideInterface,
             args = ('', for_)
             )
-        
 
-def _handle_menu(_context, menu, title, for_, name, permission):
+# transient _handle_menu registry
+_registeredMenus = {}
+
+def _handle_menu(_context, menu, title, for_, name, permission, layer=IDefaultBrowserLayer):
+
     if menu or title:
         if not (menu and title):
             raise ConfigurationError(
@@ -385,13 +388,21 @@
                 raise ConfigurationError(
                     "Menus can be specified only for single-view, not for "
                     "multi-views.")
-        return menuItemDirective(
-            _context, menu, for_[0], '@@' + name, title,
-            permission=permission)
 
+        # TODO: menuItemDirective does not handle layers.
+        # IMO this fix is just a work around and menu should 
+        # support layers too.
+        registeredTitles = _registeredMenus.setdefault(menu, {})
+        registered = registeredTitles.setdefault(title, [])
+
+        if for_[0] not in registered:
+            registered.append(for_[0])
+            return menuItemDirective(
+                _context, menu, for_[0], '@@' + name, title,
+                permission=permission)
+
     return []
 
-
 def _handle_permission(_context, permission):
     if permission == 'zope.Public':
         permission = CheckerPublic



More information about the Zope3-Checkins mailing list