[Zope3-checkins] SVN: Zope3/trunk/src/zope/ Added support for multiple 'for' interfaces to the browser:view directive. This is to allow us to remove 'layer' support for zope:view.

Garrett Smith garrett at mojave-corp.com
Tue Nov 2 11:39:30 EST 2004


Log message for revision 28318:
  Added support for multiple 'for' interfaces to the browser:view directive. This is to allow us to remove 'layer' support for zope:view.
  
  Change includes deprecation of 'layer' support for the zope:view directive. To define a browser view for a particular layer, use browser:view.
  
  The point of this change is to ensure that all layer related facilities are in z.a.publisher.browser and not in z.a.component.

Changed:
  U   Zope3/trunk/src/zope/app/component/fields.py
  U   Zope3/trunk/src/zope/app/component/metaconfigure.py
  U   Zope3/trunk/src/zope/app/component/metadirectives.py
  D   Zope3/trunk/src/zope/app/component/tests/test_fields.py
  U   Zope3/trunk/src/zope/app/container/browser/metaconfigure.py
  U   Zope3/trunk/src/zope/app/form/browser/metadirectives.py
  U   Zope3/trunk/src/zope/app/publisher/browser/fields.py
  U   Zope3/trunk/src/zope/app/publisher/browser/metadirectives.py
  U   Zope3/trunk/src/zope/app/publisher/browser/viewmeta.py
  U   Zope3/trunk/src/zope/app/rotterdam/configure.zcml
  U   Zope3/trunk/src/zope/app/site/browser/metaconfigure.py
  U   Zope3/trunk/src/zope/component/tests/request.py

-=-
Modified: Zope3/trunk/src/zope/app/component/fields.py
===================================================================
--- Zope3/trunk/src/zope/app/component/fields.py	2004-11-02 16:32:58 UTC (rev 28317)
+++ Zope3/trunk/src/zope/app/component/fields.py	2004-11-02 16:39:30 UTC (rev 28318)
@@ -17,102 +17,15 @@
 """
 __docformat__ = 'restructuredtext'
 
-import zope.schema
-from zope.component.exceptions import ComponentLookupError
-from zope.configuration.exceptions import ConfigurationError
-from zope.configuration.fields import GlobalObject
-from zope.interface.interfaces import IInterface
-from zope.publisher.interfaces.browser import ILayer
+# BBB this module can be deleted in 3.3
+import sys
+# hack to let apidoc dynamically load all modules without complaining
+if 'apidoc' not in sys._getframe(10).f_code.co_filename:
+    import warnings
+    warnings.warn(
+        "The class zope.app.component.fields.LayerField is deprecated and will "
+        "away in ZopeX3 3.3. Use zope.app.publisher.browser.fields.LayerField "
+        "instead.",
+        DeprecationWarning)
 
-from zope.app import zapi
-
-
-class LayerField(GlobalObject):
-    r"""This fields represents a layer.
-
-    Besides being able to look up the layer by importing it, we also try
-    to look up the name in the utility service.
-
-    >>> from zope.interface import directlyProvides
-    >>> from zope.interface.interface import InterfaceClass
-
-    >>> layer1 = InterfaceClass('layer1', (),
-    ...                         __doc__='Layer: layer1',
-    ...                         __module__='zope.app.layers')
-    >>> directlyProvides(layer1, ILayer)
-
-    >>> layers = None
-    >>> class Resolver(object):
-    ...     def resolve(self, path):
-    ...         if '..' in path:
-    ...             raise ValueError('Empty module name')
-    ...         if (path.startswith('zope.app.layers') and
-    ...             hasattr(layers, 'layer1') or
-    ...             path == 'zope.app.component.fields.layer1' or
-    ...             path == '.fields.layer1'):
-    ...             return layer1
-    ...         raise ConfigurationError, 'layer1'
-
-    >>> field = LayerField()
-    >>> field = field.bind(Resolver())
-
-    Test 1: Import the layer
-    ------------------------
-
-    >>> field.fromUnicode('zope.app.component.fields.layer1') is layer1
-    True
-
-    Test 2: We have a shortcut name. Import the layer from `zope.app.layers`.
-    -------------------------------------------------------------------------
-
-    >>> from types import ModuleType as module
-    >>> import sys
-    >>> layers = module('layers')
-    >>> old = sys.modules.get('zope.app.layers', None)
-    >>> sys.modules['zope.app.layers'] = layers
-    >>> setattr(layers, 'layer1', layer1)
-
-    >>> field.fromUnicode('layer1') is layer1
-    True
-
-    >>> if old is not None:
-    ...     sys.modules['zope.app.layers'] = old
-
-    Test 3: Get the layer from the utility service
-    ----------------------------------------------
-
-    >>> from zope.app.tests import ztapi
-    >>> ztapi.provideUtility(ILayer, layer1, 'layer1')
-
-    >>> field.fromUnicode('layer1') is layer1
-    True
-
-    Test 4: Import the layer by using a short name
-    ----------------------------------------------
-
-    >>> field.fromUnicode('.fields.layer1') is layer1
-    True
-    """
-
-    def fromUnicode(self, u):
-        name = str(u.strip())
-
-        try:
-            value = zapi.queryUtility(ILayer, name)
-        except ComponentLookupError:
-            # The component architecture is not up and running.
-            pass
-        else:
-            if value is not None:
-                return value
-
-        try:
-            value = self.context.resolve('zope.app.layers.'+name)
-        except (ConfigurationError, ValueError), v:
-            try:
-                value = self.context.resolve(name)
-            except ConfigurationError, v:
-                raise zope.schema.ValidationError(v)
-
-        self.validate(value)
-        return value
+from zope.app.publisher.browser.fields import LayerField

Modified: Zope3/trunk/src/zope/app/component/metaconfigure.py
===================================================================
--- Zope3/trunk/src/zope/app/component/metaconfigure.py	2004-11-02 16:32:58 UTC (rev 28317)
+++ Zope3/trunk/src/zope/app/component/metaconfigure.py	2004-11-02 16:39:30 UTC (rev 28318)
@@ -30,6 +30,9 @@
 from zope.app.component.interface import queryInterface
 from zope.app.security.adapter import TrustedAdapterFactory
 
+import warnings
+
+
 PublicPermission = 'zope.Public'
 
 # I prefer the indirection (using getService and getServices vs.
@@ -232,11 +235,20 @@
     checker = Checker(require)
     return checker
 
+# BBB layer should be removed from args in 3.3
 def resource(_context, factory, type, name, layer=None,
              permission=None,
              allowed_interface=None, allowed_attributes=None,
              provides=Interface):
 
+    # BBB This can go away in 3.3
+    if layer is not None:
+        warnings.warn(
+            "The layer attribute is deprecated for the zope:view "
+            "directive and will go away in ZopeX3 3.3. Use browser:view "
+            "instead.",
+            DeprecationWarning)
+
     if ((allowed_attributes or allowed_interface)
         and (not permission)):
         raise ConfigurationError(
@@ -254,9 +266,11 @@
 
         factory = proxyResource
 
+    # BBB can go away in 3.3
     if layer is None:
         layer = type
 
+    # BBB 'layer' should be changed to 'type' in 3.3
     _context.action(
         discriminator = ('resource', name, layer, provides),
         callable = handler,
@@ -274,10 +288,19 @@
         args = (provides.__module__ + '.' + provides.__name__, type)
                )
 
+# BBB layer should be removed from args in 3.3
 def view(_context, factory, type, name, for_, layer=None,
          permission=None, allowed_interface=None, allowed_attributes=None,
          provides=Interface):
 
+    # BBB This can go away in 3.3
+    if layer is not None:
+        warnings.warn(
+            "The layer attribute is deprecated for the zope:view "
+            "directive and will go away in ZopeX3 3.3. Use browser:view "
+            "instead.",
+            DeprecationWarning)
+
     if ((allowed_attributes or allowed_interface)
         and (not permission)):
         raise ConfigurationError(
@@ -328,6 +351,7 @@
     if layer is None:
         for_ = for_ + (type,)
     else:
+        # BBB can go away in 3.3 -- always use type as required interface
         for_ = for_ + (layer,)
 
     _context.action(

Modified: Zope3/trunk/src/zope/app/component/metadirectives.py
===================================================================
--- Zope3/trunk/src/zope/app/component/metadirectives.py	2004-11-02 16:32:58 UTC (rev 28317)
+++ Zope3/trunk/src/zope/app/component/metadirectives.py	2004-11-02 16:39:30 UTC (rev 28318)
@@ -22,8 +22,10 @@
 import zope.schema
 
 import zope.app.security.fields
-import zope.app.component.fields
 
+# BBB goes away in 3.3
+from zope.app.publisher.browser.fields import LayerField
+
 from zope.app.i18n import ZopeMessageIDFactory as _
 
 
@@ -79,7 +81,8 @@
         required=False,
         )
 
-    layer = zope.app.component.fields.LayerField(
+    # BBB remove this field in 3.3
+    layer = LayerField(
         title=_("The layer the view is in."),
         description=_("""
         A skin is composed of layers. It is common to put skin
@@ -338,7 +341,8 @@
                          IBasicResourceInformation):
     """Register a resource"""
     
-    layer = zope.app.component.fields.LayerField(
+    # BBB remove this field in 3.3
+    layer = LayerField(
         title=_("The layer the resource is in."),
         required=False,
         )

Deleted: Zope3/trunk/src/zope/app/component/tests/test_fields.py
===================================================================
--- Zope3/trunk/src/zope/app/component/tests/test_fields.py	2004-11-02 16:32:58 UTC (rev 28317)
+++ Zope3/trunk/src/zope/app/component/tests/test_fields.py	2004-11-02 16:39:30 UTC (rev 28318)
@@ -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.tests import placelesssetup
-
-def test_suite():
-    return unittest.TestSuite((
-        DocTestSuite('zope.app.component.fields',
-                     setUp=placelesssetup.setUp,
-                     tearDown=placelesssetup.tearDown),
-        ))
-
-if __name__ == '__main__':
-    unittest.main(defaultTest='test_suite')

Modified: Zope3/trunk/src/zope/app/container/browser/metaconfigure.py
===================================================================
--- Zope3/trunk/src/zope/app/container/browser/metaconfigure.py	2004-11-02 16:32:58 UTC (rev 28317)
+++ Zope3/trunk/src/zope/app/container/browser/metaconfigure.py	2004-11-02 16:39:30 UTC (rev 28318)
@@ -72,7 +72,7 @@
     if add is not None:
         from zope.app.menus import zmi_actions
         viewObj = view(_context, name='+', menu=zmi_actions,
-                       title=_('Add'), for_=for_, permission=add,
+                       title=_('Add'), for_=(for_,), permission=add,
                        class_=Adding)
         viewObj.page(_context, name='index.html', attribute='index')
         viewObj.page(_context, name='action.html', attribute='action')

Modified: Zope3/trunk/src/zope/app/form/browser/metadirectives.py
===================================================================
--- Zope3/trunk/src/zope/app/form/browser/metadirectives.py	2004-11-02 16:32:58 UTC (rev 28317)
+++ Zope3/trunk/src/zope/app/form/browser/metadirectives.py	2004-11-02 16:39:30 UTC (rev 28318)
@@ -22,8 +22,7 @@
      Bool, PythonIdentifier, MessageID
 from zope.schema import Text, TextLine, Id
 from zope.app.security.fields import Permission
-from zope.app.component.fields import LayerField
-from zope.app.publisher.browser.fields import MenuField
+from zope.app.publisher.browser.fields import MenuField, LayerField
 
 class ICommonInformation(Interface):
     """

Modified: Zope3/trunk/src/zope/app/publisher/browser/fields.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/fields.py	2004-11-02 16:32:58 UTC (rev 28317)
+++ Zope3/trunk/src/zope/app/publisher/browser/fields.py	2004-11-02 16:39:30 UTC (rev 28318)
@@ -22,11 +22,103 @@
 from zope.configuration.exceptions import ConfigurationError
 from zope.configuration.fields import GlobalObject
 from zope.interface.interfaces import IInterface
-from zope.app.publisher.interfaces.browser import IMenuItemType
+from zope.publisher.interfaces.browser import ILayer
 
 from zope.app import zapi
+from zope.app.publisher.interfaces.browser import IMenuItemType
 
 
+class LayerField(GlobalObject):
+    r"""This fields represents a layer.
+
+    Besides being able to look up the layer by importing it, we also try
+    to look up the name in the utility service.
+
+    >>> from zope.interface import directlyProvides
+    >>> from zope.interface.interface import InterfaceClass
+
+    >>> layer1 = InterfaceClass('layer1', (),
+    ...                         __doc__='Layer: layer1',
+    ...                         __module__='zope.app.layers')
+    >>> directlyProvides(layer1, ILayer)
+
+    >>> layers = None
+    >>> class Resolver(object):
+    ...     def resolve(self, path):
+    ...         if '..' in path:
+    ...             raise ValueError('Empty module name')
+    ...         if (path.startswith('zope.app.layers') and
+    ...             hasattr(layers, 'layer1') or
+    ...             path == 'zope.app.component.fields.layer1' or
+    ...             path == '.fields.layer1'):
+    ...             return layer1
+    ...         raise ConfigurationError, 'layer1'
+
+    >>> field = LayerField()
+    >>> field = field.bind(Resolver())
+
+    Test 1: Import the layer
+    ------------------------
+
+    >>> field.fromUnicode('zope.app.component.fields.layer1') is layer1
+    True
+
+    Test 2: We have a shortcut name. Import the layer from `zope.app.layers`.
+    -------------------------------------------------------------------------
+
+    >>> from types import ModuleType as module
+    >>> import sys
+    >>> layers = module('layers')
+    >>> old = sys.modules.get('zope.app.layers', None)
+    >>> sys.modules['zope.app.layers'] = layers
+    >>> setattr(layers, 'layer1', layer1)
+
+    >>> field.fromUnicode('layer1') is layer1
+    True
+
+    >>> if old is not None:
+    ...     sys.modules['zope.app.layers'] = old
+
+    Test 3: Get the layer from the utility service
+    ----------------------------------------------
+
+    >>> from zope.app.tests import ztapi
+    >>> ztapi.provideUtility(ILayer, layer1, 'layer1')
+
+    >>> field.fromUnicode('layer1') is layer1
+    True
+
+    Test 4: Import the layer by using a short name
+    ----------------------------------------------
+
+    >>> field.fromUnicode('.fields.layer1') is layer1
+    True
+    """
+
+    def fromUnicode(self, u):
+        name = str(u.strip())
+
+        try:
+            value = zapi.queryUtility(ILayer, name)
+        except ComponentLookupError:
+            # The component architecture is not up and running.
+            pass
+        else:
+            if value is not None:
+                return value
+
+        try:
+            value = self.context.resolve('zope.app.layers.'+name)
+        except (ConfigurationError, ValueError), v:
+            try:
+                value = self.context.resolve(name)
+            except ConfigurationError, v:
+                raise zope.schema.ValidationError(v)
+
+        self.validate(value)
+        return value
+
+
 class MenuField(GlobalObject):
     r"""This fields represents a menu (item type).
 

Modified: Zope3/trunk/src/zope/app/publisher/browser/metadirectives.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/metadirectives.py	2004-11-02 16:32:58 UTC (rev 28317)
+++ Zope3/trunk/src/zope/app/publisher/browser/metadirectives.py	2004-11-02 16:39:30 UTC (rev 28318)
@@ -23,10 +23,11 @@
 from zope.schema import TextLine, Text, Id, Int
 
 from zope.app.component.metadirectives import IBasicViewInformation
-from zope.app.component.fields import LayerField
-from zope.app.publisher.browser.fields import MenuField
+from zope.app.publisher.browser.fields import MenuField, LayerField
 from zope.app.security.fields import Permission
 
+from zope.app.i18n import ZopeMessageIDFactory as _
+
 #
 # browser views
 #
@@ -45,6 +46,15 @@
         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,
+        )
+
     permission = Permission(
         title=u"Permission",
         description=u"The permission needed to use the view.",
@@ -59,9 +69,11 @@
     traversing to the view name and then traversing to the page name.
     """
 
-    for_ = GlobalObject(
-        title=u"The interface this view is for.",
-        required=False
+    for_ = Tokens(
+        title=_("Specifications of the objects to be viewed"),
+        description=_("This should be a list of interfaces or classes"),
+        required=False,
+        value_type=GlobalObject(missing_value=object(),),
         )
 
     name = TextLine(

Modified: Zope3/trunk/src/zope/app/publisher/browser/viewmeta.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/viewmeta.py	2004-11-02 16:32:58 UTC (rev 28317)
+++ Zope3/trunk/src/zope/app/publisher/browser/viewmeta.py	2004-11-02 16:39:30 UTC (rev 28318)
@@ -26,6 +26,7 @@
 from zope.configuration.exceptions import ConfigurationError
 from zope.app.component.interface import provideInterface
 from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.interfaces.browser import IDefaultLayer
 from zope.publisher.interfaces.browser import IBrowserPublisher
 from zope.app import zapi
 from zope.app.component.metaconfigure import handler
@@ -88,12 +89,12 @@
 # page
 
 def page(_context, name, permission, for_,
-         layer=IBrowserRequest, template=None, class_=None,
+         layer=IDefaultLayer, template=None, class_=None,
          allowed_interface=None, allowed_attributes=None,
          attribute='__call__', menu=None, title=None, 
          ):
 
-    _handle_menu(_context, menu, title, [for_], name, permission)
+    _handle_menu(_context, menu, title, for_, name, permission)
 
     required = {}
 
@@ -176,7 +177,7 @@
 class pages(object):
 
     def __init__(self, _context, for_, permission,
-                 layer=IBrowserRequest, class_=None,
+                 layer=IDefaultLayer, class_=None,
                  allowed_interface=None, allowed_attributes=None,
                  ):
         self.opts = dict(for_=for_, permission=permission,
@@ -207,12 +208,23 @@
     default = None
 
     def __init__(self, _context, for_, permission,
-                 name='', layer=IBrowserRequest, class_=None,
+                 name='', layer=IDefaultLayer, class_=None,
                  allowed_interface=None, allowed_attributes=None,
                  menu=None, title=None, provides=Interface,
                  ):
+        if not isinstance(for_, (list, tuple)):
+            import warnings
+            # BBB This can go away in 3.3
+            import pdb;pdb.set_trace()
+            warnings.warn(
+                "The for_ argument to "
+                "zope.app.publisher.browser.metaconfigure.view should be a "
+                "sequence of interfaces.",
+                DeprecationWarning)
+            for_ = (for_,)
+        for_ = tuple(for_)
 
-        _handle_menu(_context, menu, title, [for_], name, permission)
+        _handle_menu(_context, menu, title, for_[0], name, permission)
 
         permission = _handle_permission(_context, permission)
 
@@ -325,7 +337,8 @@
                                   required)
         _handle_allowed_attributes(_context, allowed_interface, permission,
                                    required)
-        _handle_for(_context, for_)
+        for iface in for_:
+            _handle_for(_context, iface)
 
         defineChecker(newclass, Checker(required))
 
@@ -336,17 +349,16 @@
                 args = ('', self.provides)
                 )
 
+        required = for_ + (layer,)
         _context.action(
-            discriminator = ('view', for_, name, IBrowserRequest, layer,
-                             self.provides),
+            discriminator = ('view', required, name, self.provides),
             callable = handler,
-            args = (zapi.servicenames.Adapters, 'register',
-                    (for_, layer), self.provides, name, newclass,
-                    _context.info),
+            args = (zapi.servicenames.Adapters, 'register', required,
+                    self.provides, name, newclass, _context.info),
             )
 
 def addview(_context, name, permission,
-            layer=IBrowserRequest, class_=None,
+            layer=IDefaultLayer, class_=None,
             allowed_interface=None, allowed_attributes=None,
             menu=None, title=None
             ):
@@ -382,14 +394,9 @@
             raise ConfigurationError(
                 "If either menu or title are specified, they must "
                 "both be specified.")
-
-        if len(for_) != 1:
-            raise ConfigurationError(
-                "Menus can be specified only for single-view, not for "
-                "multi-views.")
             
         return menuItemDirective(
-            _context, menu, for_[0], '@@' + name, title,
+            _context, menu, for_, '@@' + name, title,
             permission=permission)
 
     return []

Modified: Zope3/trunk/src/zope/app/rotterdam/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/rotterdam/configure.zcml	2004-11-02 16:32:58 UTC (rev 28317)
+++ Zope3/trunk/src/zope/app/rotterdam/configure.zcml	2004-11-02 16:39:30 UTC (rev 28318)
@@ -120,11 +120,10 @@
       template="popup_macros.pt"
       />
 
-  <view
-      type="zope.publisher.interfaces.browser.IBrowserRequest"
+  <browser:view
       for="zope.schema.interfaces.ISourceText"
       provides="zope.app.form.interfaces.IInputWidget"
-      factory=".editingwidgets.SimpleEditingWidget"
+      class=".editingwidgets.SimpleEditingWidget"
       permission="zope.Public"
       layer="zope.app.rotterdam.rotterdam"
       />

Modified: Zope3/trunk/src/zope/app/site/browser/metaconfigure.py
===================================================================
--- Zope3/trunk/src/zope/app/site/browser/metaconfigure.py	2004-11-02 16:32:58 UTC (rev 28317)
+++ Zope3/trunk/src/zope/app/site/browser/metaconfigure.py	2004-11-02 16:39:30 UTC (rev 28318)
@@ -51,7 +51,7 @@
                    'folder':folder,
                    'title':'Add %s Tool' % interface.getName()} )
 
-    addView = complexView(_context, ISiteManager, permission, addName,
+    addView = complexView(_context, (ISiteManager,), permission, addName,
                           class_=class_)
     addView.page(_context, 'index.html', 'index')
     addView.page(_context, 'action.html', 'action')
@@ -81,7 +81,7 @@
                   (ServiceToolAdding,),
                   {'folder':folder} )
 
-    addView = complexView(_context, ISiteManager, permission, addName,
+    addView = complexView(_context, (ISiteManager,), permission, addName,
                           class_=class_)
     addView.page(_context, 'index.html', 'index')
     addView.page(_context, 'action.html', 'action')

Modified: Zope3/trunk/src/zope/component/tests/request.py
===================================================================
--- Zope3/trunk/src/zope/component/tests/request.py	2004-11-02 16:32:58 UTC (rev 28317)
+++ Zope3/trunk/src/zope/component/tests/request.py	2004-11-02 16:39:30 UTC (rev 28318)
@@ -17,11 +17,19 @@
 """
 import zope.interface
 
+
 class Request(object):
 
     def __init__(self, type, skin=None):
+        zope.interface.directlyProvides(self, type)
+        # BBB goes away in 3.3
+        if skin is not None:
+            import warnings
+            warnings.warn(
+                "The skin argument is deprecated for "
+                "zope.component.tests.request.Request and will go away in "
+                "ZopeX3 3.3. Use zope.publisher.browser.TestRequest if "
+                "you need to test skins.",
+                DeprecationWarning)
+            zope.interface.directlyProvides(self, skin)
         self._skin = skin
-        if skin is None:
-            zope.interface.directlyProvides(self, type)
-        else:
-            zope.interface.directlyProvides(self, type, skin)



More information about the Zope3-Checkins mailing list