[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