[Checkins] SVN: zope.publisher/trunk/ Merge the zope.app.publisher refactoring results from my sandbox.
Dan Korostelev
nadako at gmail.com
Thu Aug 27 10:49:25 EDT 2009
Log message for revision 103282:
Merge the zope.app.publisher refactoring results from my sandbox.
Changed:
U zope.publisher/trunk/CHANGES.txt
U zope.publisher/trunk/setup.py
U zope.publisher/trunk/src/zope/publisher/browser.py
U zope.publisher/trunk/src/zope/publisher/configure.zcml
U zope.publisher/trunk/src/zope/publisher/defaultview.py
U zope.publisher/trunk/src/zope/publisher/interfaces/ftp.py
U zope.publisher/trunk/src/zope/publisher/interfaces/http.py
U zope.publisher/trunk/src/zope/publisher/interfaces/xmlrpc.py
A zope.publisher/trunk/src/zope/publisher/meta.zcml
U zope.publisher/trunk/src/zope/publisher/tests/test_browserlanguages.py
U zope.publisher/trunk/src/zope/publisher/tests/test_browserrequest.py
A zope.publisher/trunk/src/zope/publisher/tests/test_zcml.py
U zope.publisher/trunk/src/zope/publisher/xmlrpc.py
A zope.publisher/trunk/src/zope/publisher/zcml.py
-=-
Modified: zope.publisher/trunk/CHANGES.txt
===================================================================
--- zope.publisher/trunk/CHANGES.txt 2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/CHANGES.txt 2009-08-27 14:49:25 UTC (rev 103282)
@@ -1,9 +1,17 @@
CHANGES
=======
-3.8.1 (unreleased)
+3.9.0 (unreleased)
------------------
+- Some parts of zope.app.publisher packages was moved into this package
+ during zope.app.publisher refactoring:
+
+ * IModifiableUserPreferredLanguages adapter for requests
+ * browser:defaultView and browser:defaultSkin ZCML directives
+ * IHTTPView, IXMLRPCView and like interfaces
+ * security ZCML declarations for some of zope.publisher classes
+
- Introduced ``IReRaiseException`` interface. If during publishing an
exception occurs and for this exception an adapter is available that
returns ``False`` on being called, the exception won't be reraised
@@ -21,6 +29,9 @@
- Removed behavior of doing a time.sleep in the supportsRetry http request.
+- Add a fix for Internet Explorer versions that upload files will full
+ filesystem paths as filenames.
+
3.8.0 (2009-05-23)
------------------
Modified: zope.publisher/trunk/setup.py
===================================================================
--- zope.publisher/trunk/setup.py 2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/setup.py 2009-08-27 14:49:25 UTC (rev 103282)
@@ -23,7 +23,7 @@
"""
setup(name='zope.publisher',
- version='3.8.1dev',
+ version='3.9.0dev',
url='http://pypi.python.org/pypi/zope.publisher',
license='ZPL 2.1',
author='Zope Corporation and Contributors',
@@ -44,6 +44,7 @@
'zope.authentication',
'zope.browser',
'zope.component',
+ 'zope.configuration',
'zope.event',
'zope.exceptions',
'zope.i18n',
Modified: zope.publisher/trunk/src/zope/publisher/browser.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/browser.py 2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/browser.py 2009-08-27 14:49:25 UTC (rev 103282)
@@ -32,6 +32,7 @@
from zope.interface import implements, directlyProvides
from zope.i18n.interfaces import IUserPreferredLanguages
from zope.i18n.interfaces import IUserPreferredCharsets
+from zope.i18n.interfaces import IModifiableUserPreferredLanguages
from zope.location import Location
from zope.publisher.interfaces import NotFound
@@ -622,7 +623,10 @@
d[m] = getattr(file,m)
self.headers = aFieldStorage.headers
- self.filename = unicode(aFieldStorage.filename, 'UTF-8')
+ filename = unicode(aFieldStorage.filename, 'UTF-8')
+ # fix for IE full paths
+ filename = filename[filename.rfind('\\')+1:].strip()
+ self.filename = filename
class RedirectingBrowserRequest(BrowserRequest):
"""Browser requests that redirect when the actual and effective URLs differ
@@ -823,6 +827,49 @@
return [lang for quality, lang in accepts]
+class NotCompatibleAdapterError(Exception):
+ """Adapter not compatible with
+ zope.i18n.interfaces.IModifiableBrowserLanguages has been used.
+ """
+
+BROWSER_LANGUAGES_KEY = "zope.publisher.browser.IUserPreferredLanguages"
+
+class CacheableBrowserLanguages(BrowserLanguages):
+
+ implements(IUserPreferredLanguages)
+
+ def getPreferredLanguages(self):
+ languages_data = self._getLanguagesData()
+ if "overridden" in languages_data:
+ return languages_data["overridden"]
+ elif "cached" not in languages_data:
+ languages_data["cached"] = super(
+ CacheableBrowserLanguages, self).getPreferredLanguages()
+ return languages_data["cached"]
+
+ def _getLanguagesData(self):
+ annotations = self.request.annotations
+ languages_data = annotations.get(BROWSER_LANGUAGES_KEY)
+ if languages_data is None:
+ annotations[BROWSER_LANGUAGES_KEY] = languages_data = {}
+ return languages_data
+
+class ModifiableBrowserLanguages(CacheableBrowserLanguages):
+
+ implements(IModifiableUserPreferredLanguages)
+
+ def setPreferredLanguages(self, languages):
+ languages_data = self.request.annotations.get(BROWSER_LANGUAGES_KEY)
+ if languages_data is None:
+ # Better way to create a compatible with
+ # IModifiableUserPreferredLanguages adapter is to use
+ # CacheableBrowserLanguages as base class or as example.
+ raise NotCompatibleAdapterError("Adapter not compatible with "
+ "zope.i18n.interfaces.IModifiableBrowserLanguages "
+ "has been used.")
+ languages_data["overridden"] = languages
+ self.request.setupLocale()
+
class BrowserView(Location):
"""Browser View.
Modified: zope.publisher/trunk/src/zope/publisher/configure.zcml
===================================================================
--- zope.publisher/trunk/src/zope/publisher/configure.zcml 2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/configure.zcml 2009-08-27 14:49:25 UTC (rev 103282)
@@ -16,14 +16,59 @@
zcml:condition="installed zope.annotation"
interface="zope.annotation.interfaces.IAttributeAnnotatable"
/>
+ <require
+ permission="zope.View"
+ interface="zope.publisher.interfaces.http.IHTTPApplicationRequest"/>
</class>
+ <class class="zope.publisher.http.URLGetter">
+ <allow attributes="get __getitem__ __str__" />
+ </class>
+
+ <class class="zope.publisher.http.DirectResult">
+ <allow interface="zope.publisher.http.IResult" />
+ </class>
+
+ <class class="zope.publisher.browser.BrowserRequest">
+ <allow
+ interface="zope.publisher.interfaces.browser.IBrowserApplicationRequest"
+ attributes="response locale __str__"
+ />
+ </class>
+
+ <class class="zope.publisher.browser.TestRequest">
+ <allow
+ interface="zope.publisher.interfaces.browser.IBrowserApplicationRequest"
+ attributes="response"
+ />
+ </class>
+
+ <class class="zope.publisher.browser.BrowserResponse">
+ <allow
+ interface="zope.publisher.interfaces.http.IHTTPResponse"
+ />
+ </class>
+
<adapter factory="zope.publisher.http.HTTPCharsets" />
+
+ <adapter
+ factory=".browser.ModifiableBrowserLanguages"
+ for="zope.publisher.interfaces.http.IHTTPRequest"
+ provides="zope.i18n.interfaces.IModifiableUserPreferredLanguages"
+ />
<class class="xmlrpclib.Binary">
<allow attributes="data encode decode" />
</class>
+ <class class="xmlrpclib.Fault">
+ <allow attributes="faultCode faultString" />
+ </class>
+
+ <class class="xmlrpclib.DateTime">
+ <allow attributes="value" />
+ </class>
+
<adapter factory=".xmlrpc.ListPreMarshaller" />
<adapter factory=".xmlrpc.TuplePreMarshaller" />
<adapter factory=".xmlrpc.BinaryPreMarshaller" />
Modified: zope.publisher/trunk/src/zope/publisher/defaultview.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/defaultview.py 2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/defaultview.py 2009-08-27 14:49:25 UTC (rev 103282)
@@ -43,7 +43,6 @@
a context.
"""
-# TODO: needs tests
def getDefaultViewName(object, request, context=None):
name = queryDefaultViewName(object, request, context=context)
if name is not None:
Modified: zope.publisher/trunk/src/zope/publisher/interfaces/ftp.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/interfaces/ftp.py 2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/interfaces/ftp.py 2009-08-27 14:49:25 UTC (rev 103282)
@@ -22,12 +22,15 @@
from zope.publisher.interfaces import IPublishTraverse
from zope.publisher.interfaces import IRequest
+from zope.publisher.interfaces import IView
-
class IFTPRequest(IRequest):
"""FTP Request
"""
+class IFTPView(IView):
+ """FTP View"""
+
class IFTPCredentials(Interface):
def _authUserPW():
Modified: zope.publisher/trunk/src/zope/publisher/interfaces/http.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/interfaces/http.py 2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/interfaces/http.py 2009-08-27 14:49:25 UTC (rev 103282)
@@ -27,6 +27,7 @@
from zope.publisher.interfaces import IPublishTraverse
from zope.publisher.interfaces import IRequest
from zope.publisher.interfaces import IResponse
+from zope.publisher.interfaces import IView
class IVirtualHostRequest(Interface):
@@ -214,6 +215,10 @@
"""
+class IHTTPView(IView):
+ "HTTP View"
+
+
class IHTTPCredentials(Interface):
# TODO: Eventially this will be a different method
Modified: zope.publisher/trunk/src/zope/publisher/interfaces/xmlrpc.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/interfaces/xmlrpc.py 2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/interfaces/xmlrpc.py 2009-08-27 14:49:25 UTC (rev 103282)
@@ -20,7 +20,7 @@
from zope.interface import Interface
-from zope.publisher.interfaces import IPublication
+from zope.publisher.interfaces import IPublication, IView
from zope.publisher.interfaces import IPublishTraverse
from zope.publisher.interfaces.http import IHTTPRequest
@@ -43,11 +43,11 @@
"""XML-RPC Request
"""
+class IXMLRPCView(IView):
+ """XMLRPC View"""
+
class IXMLRPCPremarshaller(Interface):
"""Pre-Marshaller to remove proxies for xmlrpclib"""
def __call__(self):
"""Return the given object without proxies."""
-
-
-
Copied: zope.publisher/trunk/src/zope/publisher/meta.zcml (from rev 103281, Sandbox/nadako/zope.publisher/src/zope/publisher/meta.zcml)
===================================================================
--- zope.publisher/trunk/src/zope/publisher/meta.zcml (rev 0)
+++ zope.publisher/trunk/src/zope/publisher/meta.zcml 2009-08-27 14:49:25 UTC (rev 103282)
@@ -0,0 +1,19 @@
+<configure xmlns:meta="http://namespaces.zope.org/meta">
+
+ <meta:directives namespace="http://namespaces.zope.org/browser">
+
+ <meta:directive
+ name="defaultView"
+ schema=".zcml.IDefaultViewDirective"
+ handler=".zcml.defaultView"
+ />
+
+ <meta:directive
+ name="defaultSkin"
+ schema=".zcml.IDefaultSkinDirective"
+ handler=".zcml.defaultSkin"
+ />
+
+ </meta:directives>
+
+</configure>
Modified: zope.publisher/trunk/src/zope/publisher/tests/test_browserlanguages.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/tests/test_browserlanguages.py 2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/tests/test_browserlanguages.py 2009-08-27 14:49:25 UTC (rev 103282)
@@ -18,8 +18,10 @@
import unittest
from zope.publisher.browser import BrowserLanguages
+from zope.publisher.browser import CacheableBrowserLanguages
+from zope.publisher.browser import ModifiableBrowserLanguages
+from zope.publisher.browser import NotCompatibleAdapterError
-
# Note: The expected output is in order of preference,
# empty 'q=' means 'q=1', and if theres more than one
# empty, we assume they are in order of preference.
@@ -54,10 +56,44 @@
self.assertEqual(list(browser_languages.getPreferredLanguages()),
expected)
+class CacheableBrowserLanguagesTests(BrowserLanguagesTest):
+ def factory(self, request):
+ return CacheableBrowserLanguages(request)
+
+ def test_cached_languages(self):
+ eq = self.failUnlessEqual
+ request = TestRequest("da, en, pt")
+ browser_languages = self.factory(request)
+ eq(list(browser_languages.getPreferredLanguages()), ["da", "en", "pt"])
+ request["HTTP_ACCEPT_LANGUAGE"] = "ru, en"
+ eq(list(browser_languages.getPreferredLanguages()), ["da", "en", "pt"])
+
+class ModifiableBrowserLanguagesTests(CacheableBrowserLanguagesTests):
+
+ def factory(self, request):
+ return ModifiableBrowserLanguages(request)
+
+ def test_setPreferredLanguages(self):
+ eq = self.failUnlessEqual
+ request = TestRequest("da, en, pt")
+ browser_languages = self.factory(request)
+ eq(list(browser_languages.getPreferredLanguages()), ["da", "en", "pt"])
+ browser_languages.setPreferredLanguages(["ru", "en"])
+ self.failUnless(request.localized)
+ eq(list(browser_languages.getPreferredLanguages()), ["ru", "en"])
+
+ def test_conflicting_adapters(self):
+ request = TestRequest("da, en, pt")
+ not_compatible_browser_languages = BrowserLanguages(request)
+ browser_languages = self.factory(request)
+ self.assertRaises(NotCompatibleAdapterError,
+ browser_languages.setPreferredLanguages, ["ru", "en"])
+
+
def test_suite():
- loader=unittest.TestLoader()
- return loader.loadTestsFromTestCase(BrowserLanguagesTest)
-
-if __name__=='__main__':
- unittest.TextTestRunner().run(test_suite())
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(BrowserLanguagesTest))
+ suite.addTest(unittest.makeSuite(CacheableBrowserLanguagesTests))
+ suite.addTest(unittest.makeSuite(ModifiableBrowserLanguagesTests))
+ return suite
Modified: zope.publisher/trunk/src/zope/publisher/tests/test_browserrequest.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/tests/test_browserrequest.py 2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/tests/test_browserrequest.py 2009-08-27 14:49:25 UTC (rev 103282)
@@ -47,6 +47,15 @@
-----------------------------1--
""" % ('test' * 1000)
+IE_FILE_BODY = """-----------------------------1
+Content-Disposition: form-data; name="upload"; filename="C:\\Windows\\notepad.exe"
+Content-Type: text/plain
+
+Some data
+-----------------------------1--
+"""
+
+
def publish(request):
publish_(request, handle_errors=0)
@@ -200,6 +209,11 @@
request.processInputs()
self.assert_(request.form['upload'].name)
+ request = self._createRequest(extra, body=IE_FILE_BODY)
+ request.processInputs()
+ self.assertEquals(request.form['upload'].filename, 'notepad.exe')
+
+
def testDefault2(self):
extra = {'PATH_INFO': '/folder/item2/view'}
request = self._createRequest(extra)
Copied: zope.publisher/trunk/src/zope/publisher/tests/test_zcml.py (from rev 103281, Sandbox/nadako/zope.publisher/src/zope/publisher/tests/test_zcml.py)
===================================================================
--- zope.publisher/trunk/src/zope/publisher/tests/test_zcml.py (rev 0)
+++ zope.publisher/trunk/src/zope/publisher/tests/test_zcml.py 2009-08-27 14:49:25 UTC (rev 103282)
@@ -0,0 +1,169 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 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.
+#
+##############################################################################
+"""Tests for browser:defaultSkin and browser:defaultView directives
+
+$Id: tests.py 103163 2009-08-24 16:22:07Z nadako $
+"""
+from cStringIO import StringIO
+import unittest
+
+from zope.testing import cleanup
+from zope import component
+
+from zope.configuration.xmlconfig import XMLConfig, xmlconfig
+from zope.publisher.browser import TestRequest, BrowserView
+from zope.publisher.defaultview import getDefaultViewName
+from zope.publisher.interfaces import IDefaultViewName, IDefaultSkin
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.interface import Interface, implements, providedBy, directlyProvides
+
+import zope.publisher
+
+class IOb(Interface):
+ pass
+
+class Ob(object):
+ implements(IOb)
+
+class ITestLayer(IBrowserRequest):
+ """Test Layer."""
+
+class ITestSkin(ITestLayer):
+ """Test Skin."""
+
+class V1(BrowserView):
+ pass
+
+class V2(BrowserView):
+ pass
+
+
+request = TestRequest()
+ob = Ob()
+
+template = """<configure
+ xmlns='http://namespaces.zope.org/zope'
+ xmlns:browser='http://namespaces.zope.org/browser'
+ i18n_domain='zope'>
+ %s
+ </configure>"""
+
+class Test(cleanup.CleanUp, unittest.TestCase):
+
+ def setUp(self):
+ super(Test, self).setUp()
+ XMLConfig('meta.zcml', zope.publisher)()
+
+ def testDefaultView(self):
+ self.assertTrue(
+ component.queryMultiAdapter((ob, request), IDefaultViewName) is None)
+ xmlconfig(StringIO(template % (
+ '''
+ <browser:defaultView
+ name="test"
+ for="zope.publisher.tests.test_zcml.IOb" />
+ '''
+ )))
+
+ self.assertEqual(getDefaultViewName(ob, request), 'test')
+
+ def testDefaultViewWithLayer(self):
+ class FakeRequest(TestRequest):
+ implements(ITestLayer)
+ request2 = FakeRequest()
+
+ self.assertEqual(
+ component.queryMultiAdapter((ob, request2), IDefaultViewName),
+ None)
+
+ xmlconfig(StringIO(template % (
+ '''
+ <browser:defaultView
+ for="zope.publisher.tests.test_zcml.IOb"
+ name="test"
+ />
+ <browser:defaultView
+ for="zope.publisher.tests.test_zcml.IOb"
+ layer="zope.publisher.tests.test_zcml.ITestLayer"
+ name="test2"
+ />
+ '''
+ )))
+
+ self.assertEqual(
+ zope.publisher.defaultview.getDefaultViewName(ob, request2),
+ 'test2')
+ self.assertEqual(
+ zope.publisher.defaultview.getDefaultViewName(ob, request),
+ 'test')
+
+ def testDefaultViewForClass(self):
+ self.assertEqual(
+ component.queryMultiAdapter((ob, request), IDefaultViewName),
+ None)
+
+ xmlconfig(StringIO(template % (
+ '''
+ <browser:defaultView
+ for="zope.publisher.tests.test_zcml.Ob"
+ name="test"
+ />
+ '''
+ )))
+
+ self.assertEqual(
+ zope.publisher.defaultview.getDefaultViewName(ob, request),
+ 'test')
+
+ def testDefaultSkin(self):
+ request = TestRequest()
+ self.assertEqual(
+ component.queryMultiAdapter((ob, request), name='test'),
+ None)
+
+ XMLConfig('meta.zcml', component)()
+ xmlconfig(StringIO(template % (
+ '''
+ <interface
+ interface="
+ zope.publisher.tests.test_zcml.ITestSkin"
+ type="zope.publisher.interfaces.browser.IBrowserSkinType"
+ name="Test Skin"
+ />
+ <browser:defaultSkin name="Test Skin" />
+ <view
+ for="zope.publisher.tests.test_zcml.IOb"
+ type="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
+ name="test"
+ factory="zope.publisher.tests.test_zcml.V1"
+ />
+ <view
+ for="zope.publisher.tests.test_zcml.IOb"
+ type="zope.publisher.tests.test_zcml.ITestLayer"
+ name="test"
+ factory="zope.publisher.tests.test_zcml.V2"
+ />
+ '''
+ )))
+
+ # Simulate Zope Publication behavior in beforeTraversal()
+ adapters = component.getSiteManager().adapters
+ skin = adapters.lookup((providedBy(request),), IDefaultSkin, '')
+ directlyProvides(request, skin)
+
+ v = component.queryMultiAdapter((ob, request), name='test')
+ self.assertTrue(isinstance(v, V2))
+
+def test_suite():
+ return unittest.makeSuite(Test)
Modified: zope.publisher/trunk/src/zope/publisher/xmlrpc.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/xmlrpc.py 2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/xmlrpc.py 2009-08-27 14:49:25 UTC (rev 103282)
@@ -28,7 +28,7 @@
import zope.interface
from zope.interface import implements
from zope.publisher.interfaces.xmlrpc import \
- IXMLRPCPublisher, IXMLRPCRequest, IXMLRPCPremarshaller
+ IXMLRPCPublisher, IXMLRPCRequest, IXMLRPCPremarshaller, IXMLRPCView
from zope.publisher.http import HTTPRequest, HTTPResponse, DirectResult
from zope.security.proxy import isinstance
@@ -162,6 +162,16 @@
# XML-RPC prefers a status of 200 ("ok") even when reporting errors.
self.setStatus(200)
+
+class XMLRPCView(object):
+ """A base XML-RPC view that can be used as mix-in for XML-RPC views."""
+ implements(IXMLRPCView)
+
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+
class PreMarshallerBase(object):
"""Abstract base class for pre-marshallers."""
zope.interface.implements(IXMLRPCPremarshaller)
Copied: zope.publisher/trunk/src/zope/publisher/zcml.py (from rev 103281, Sandbox/nadako/zope.publisher/src/zope/publisher/zcml.py)
===================================================================
--- zope.publisher/trunk/src/zope/publisher/zcml.py (rev 0)
+++ zope.publisher/trunk/src/zope/publisher/zcml.py 2009-08-27 14:49:25 UTC (rev 103282)
@@ -0,0 +1,120 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 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.
+#
+##############################################################################
+"""Default view and default skin ZCML configuration feature.
+
+$Id: metaconfigure.py 103163 2009-08-24 16:22:07Z nadako $
+"""
+from zope import component
+from zope.component.interface import provideInterface
+from zope.component.zcml import handler
+from zope.configuration.fields import GlobalObject, GlobalInterface
+from zope.interface import Interface
+from zope.publisher.interfaces import IDefaultViewName
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.interfaces.browser import IBrowserSkinType
+from zope.publisher.interfaces.browser import IDefaultSkin
+from zope.schema import TextLine
+
+
+class IDefaultSkinDirective(Interface):
+ """Sets the default browser skin"""
+
+ name = TextLine(
+ title=u"Default skin name",
+ description=u"Default skin name",
+ required=True
+ )
+
+
+class IDefaultViewDirective(Interface):
+ """
+ The name of the view that should be the default.
+
+ This name refers to view that should be the
+ view used by default (if no view name is supplied
+ explicitly).
+ """
+
+ name = TextLine(
+ title=u"The name of the view that should be the default.",
+ description=u"""
+ This name refers to view that should be the view used by
+ default (if no view name is supplied explicitly).""",
+ required=True
+ )
+
+ for_ = GlobalObject(
+ title=u"The interface this view is the default for.",
+ description=u"""Specifies the interface for which the view is
+ registered. All objects implementing this interface can make use of
+ this view. If this attribute is not specified, the view is available
+ for all objects.""",
+ required=False
+ )
+
+ layer = GlobalInterface(
+ title=u"The layer the default view is declared for",
+ description=u"The default layer for which the default view is "
+ u"applicable. By default it is applied to all layers.",
+ required=False
+ )
+
+
+def setDefaultSkin(name, info=''):
+ """Set the default skin.
+
+ >>> from zope.interface import directlyProvides
+ >>> from zope.app.testing import ztapi
+
+ >>> class Skin1: pass
+ >>> directlyProvides(Skin1, IBrowserSkinType)
+
+ >>> ztapi.provideUtility(IBrowserSkinType, Skin1, 'Skin1')
+ >>> setDefaultSkin('Skin1')
+ >>> adapters = component.getSiteManager().adapters
+
+ Lookup the default skin for a request that has the
+
+ >>> adapters.lookup((IBrowserRequest,), IDefaultSkin, '') is Skin1
+ True
+ """
+ skin = component.getUtility(IBrowserSkinType, name)
+ handler('registerAdapter',
+ skin, (IBrowserRequest,), IDefaultSkin, '', info),
+
+
+def defaultSkin(_context, name):
+
+ _context.action(
+ discriminator = 'defaultSkin',
+ callable = setDefaultSkin,
+ args = (name, _context.info)
+ )
+
+
+def defaultView(_context, name, for_=None, layer=IBrowserRequest):
+
+ _context.action(
+ discriminator = ('defaultViewName', for_, layer, name),
+ callable = handler,
+ args = ('registerAdapter',
+ name, (for_, layer), IDefaultViewName, '', _context.info)
+ )
+
+ if for_ is not None:
+ _context.action(
+ discriminator = None,
+ callable = provideInterface,
+ args = ('', for_)
+ )
More information about the Checkins
mailing list