[Checkins] SVN: Sandbox/nadako/zope.app.publisher/ Page directives were moved into zope.browserpage package.
Dan Korostelev
nadako at gmail.com
Mon Aug 24 12:22:07 EDT 2009
Log message for revision 103163:
Page directives were moved into zope.browserpage package.
Changed:
U Sandbox/nadako/zope.app.publisher/CHANGES.txt
U Sandbox/nadako/zope.app.publisher/buildout.cfg
U Sandbox/nadako/zope.app.publisher/setup.py
U Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/meta.zcml
U Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/metaconfigure.py
U Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/metadirectives.py
A Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests.py
U Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/viewmeta.py
-=-
Modified: Sandbox/nadako/zope.app.publisher/CHANGES.txt
===================================================================
--- Sandbox/nadako/zope.app.publisher/CHANGES.txt 2009-08-24 15:58:56 UTC (rev 103162)
+++ Sandbox/nadako/zope.app.publisher/CHANGES.txt 2009-08-24 16:22:07 UTC (rev 103163)
@@ -15,7 +15,12 @@
See zope.ptresource's CHANGES.txt for more information.
* ``zope.browsermenu`` - the menu mechanism was moved here completely.
-
+
+ * ``zope.browserpage`` - the browser:page directive and friends were
+ moved here. Also, these directives don't depend hardly on menu system
+ anymore, so they simply ignore the "menu" argument when zope.browsermenu
+ is not available.
+
Backward-compatibility imports are provided, so there should not be much impact
for those who uses old imports.
Modified: Sandbox/nadako/zope.app.publisher/buildout.cfg
===================================================================
--- Sandbox/nadako/zope.app.publisher/buildout.cfg 2009-08-24 15:58:56 UTC (rev 103162)
+++ Sandbox/nadako/zope.app.publisher/buildout.cfg 2009-08-24 16:22:07 UTC (rev 103163)
@@ -4,6 +4,7 @@
../zope.browserresource
../zope.ptresource
../zope.browsermenu
+ ../zope.browserpage
parts = test coverage-test coverage-report pydev
[test]
Modified: Sandbox/nadako/zope.app.publisher/setup.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/setup.py 2009-08-24 15:58:56 UTC (rev 103162)
+++ Sandbox/nadako/zope.app.publisher/setup.py 2009-08-24 16:22:07 UTC (rev 103163)
@@ -61,6 +61,7 @@
'zope.browserresource',
'zope.ptresource',
'zope.browsermenu',
+ 'zope.browserpage',
],
extras_require={
'test': ['zope.testing',
Modified: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/meta.zcml
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/meta.zcml 2009-08-24 15:58:56 UTC (rev 103162)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/meta.zcml 2009-08-24 16:22:07 UTC (rev 103163)
@@ -5,61 +5,17 @@
<include package="zope.browserresource" file="meta.zcml" />
<include package="zope.browsermenu" file="meta.zcml" />
+ <include package="zope.browserpage" file="meta.zcml" />
<meta:directives namespace="http://namespaces.zope.org/browser">
- <!-- browser views -->
-
- <meta:complexDirective
- name="view"
- schema=".metadirectives.IViewDirective"
- handler=".viewmeta.view"
- >
-
- <meta:subdirective
- name="page"
- schema=".metadirectives.IViewPageSubdirective"
- />
-
- <meta:subdirective
- name="defaultPage"
- schema=".metadirectives.IViewDefaultPageSubdirective"
- />
-
- </meta:complexDirective>
-
<meta:directive
name="defaultView"
schema=".metadirectives.IDefaultViewDirective"
handler=".metaconfigure.defaultView"
/>
-
- <!-- browser pages -->
-
<meta:directive
- name="page"
- schema=".metadirectives.IPageDirective"
- handler=".viewmeta.page"
- />
-
- <meta:complexDirective
- name="pages"
- schema=".metadirectives.IPagesDirective"
- handler=".viewmeta.pages"
- >
-
- <meta:subdirective
- name="page"
- schema=".metadirectives.IPagesPageSubdirective"
- />
-
- </meta:complexDirective>
-
-
- <!-- misc. directives -->
-
- <meta:directive
name="defaultSkin"
schema=".metadirectives.IDefaultSkinDirective"
handler=".metaconfigure.defaultSkin"
Modified: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/metaconfigure.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/metaconfigure.py 2009-08-24 15:58:56 UTC (rev 103162)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/metaconfigure.py 2009-08-24 16:22:07 UTC (rev 103163)
@@ -30,7 +30,7 @@
from zope.app.publisher.browser.resourcemeta import resource
from zope.app.publisher.browser.resourcemeta import resourceDirectory
from zope.app.publisher.browser.i18nresourcemeta import I18nResource
-from zope.app.publisher.browser.viewmeta import view
+from zope.browserpage.metaconfigure import view
def setDefaultSkin(name, info=''):
Modified: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/metadirectives.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/metadirectives.py 2009-08-24 15:58:56 UTC (rev 103162)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/metadirectives.py 2009-08-24 16:22:07 UTC (rev 103163)
@@ -17,15 +17,10 @@
$Id$
"""
-from zope.interface import Interface
from zope.configuration.fields import GlobalObject, GlobalInterface
-from zope.configuration.fields import Tokens, Path, PythonIdentifier, MessageID
-from zope.schema import TextLine, Id, Int, Bool
-from zope.security.zcml import Permission
+from zope.interface import Interface
+from zope.schema import TextLine
-from zope.component.zcml import IBasicViewInformation
-from zope.browsermenu.field import MenuField
-
# BBB imports
from zope.browserresource.metadirectives import (
IBasicResourceInformation,
@@ -45,129 +40,26 @@
ISubMenuItemDirective,
IAddMenuItemDirective,
)
+from zope.browserpage.metadirectives import (
+ IPagesDirective,
+ IViewDirective,
+ IViewPageSubdirective,
+ IViewDefaultPageSubdirective,
+ IPagesPageSubdirective,
+ IPageDirective,
+)
-#
-# browser views
-#
-class IPagesDirective(IBasicViewInformation):
+class IDefaultSkinDirective(Interface):
+ """Sets the default browser skin
"""
- Define multiple pages without repeating all of the parameters.
- The pages directive allows multiple page views to be defined
- without repeating the 'for', 'permission', 'class', 'layer',
- 'allowed_attributes', and 'allowed_interface' attributes.
- """
-
- for_ = GlobalObject(
- title=u"The interface or class this view is for.",
- required=False
- )
-
- permission = Permission(
- title=u"Permission",
- description=u"The permission needed to use the view.",
- required=True
- )
-
-class IViewDirective(IPagesDirective):
- """
- The view directive defines a view that has subpages.
-
- The pages provided by the defined view are accessed by first
- traversing to the view name and then traversing to the page name.
- """
-
- for_ = GlobalInterface(
- title=u"The interface this view is for.",
- required=False
- )
-
name = TextLine(
- title=u"The name of the view.",
- description=u"The name shows up in URLs/paths. For example 'foo'.",
- required=False,
- default=u'',
- )
-
- menu = MenuField(
- title=u"The browser menu to include the page (view) in.",
- description=u"""
- Many views are included in menus. It's convenient to name
- the menu in the page directive, rather than having to give a
- separate menuItem directive. 'zmi_views' is the menu most often
- used in the Zope management interface.
- </description>
- """,
- required=False
- )
-
- title = MessageID(
- title=u"The browser menu label for the page (view)",
- description=u"""
- This attribute must be supplied if a menu attribute is
- supplied.
- """,
- required=False
- )
-
- provides = GlobalInterface(
- title=u"The interface this view provides.",
- description=u"""
- A view can provide an interface. This would be used for
- views that support other views.""",
- required=False,
- default=Interface,
- )
-
-class IViewPageSubdirective(Interface):
- """
- Subdirective to IViewDirective.
- """
-
- name = TextLine(
- title=u"The name of the page (view)",
- description=u"""
- The name shows up in URLs/paths. For example 'foo' or
- 'foo.html'. This attribute is required unless you use the
- subdirective 'page' to create sub views. If you do not have
- sub pages, it is common to use an extension for the view name
- such as '.html'. If you do have sub pages and you want to
- provide a view name, you shouldn't use extensions.""",
+ title=u"Default skin name",
+ description=u"Default skin name",
required=True
)
- attribute = PythonIdentifier(
- title=u"The name of the view attribute implementing the page.",
- description=u"""
- This refers to the attribute (method) on the view that is
- implementing a specific sub page.""",
- required=False
- )
-
- template = Path(
- title=u"The name of a template that implements the page.",
- description=u"""
- Refers to a file containing a page template (should end in
- extension '.pt' or '.html').""",
- required=False
- )
-
-class IViewDefaultPageSubdirective(Interface):
- """
- Subdirective to IViewDirective.
- """
-
- name = TextLine(
- title=u"The name of the page that is the default.",
- description=u"""
- The named page will be used as the default if no name is
- specified explicitly in the path. If no defaultPage directive
- is supplied, the default page will be the first page
- listed.""",
- required=True
- )
-
class IDefaultViewDirective(Interface):
"""
The name of the view that should be the default.
@@ -200,52 +92,3 @@
u"applicable. By default it is applied to all layers.",
required=False
)
-
-#
-# browser pages
-#
-
-class IPagesPageSubdirective(IViewPageSubdirective):
- """
- Subdirective to IPagesDirective
- """
-
- menu = MenuField(
- title=u"The browser menu to include the page (view) in.",
- description=u"""
- Many views are included in menus. It's convenient to name the
- menu in the page directive, rather than having to give a
- separate menuItem directive.""",
- required=False
- )
-
- title = MessageID(
- title=u"The browser menu label for the page (view)",
- description=u"""
- This attribute must be supplied if a menu attribute is
- supplied.""",
- required=False
- )
-
-class IPageDirective(IPagesDirective, IPagesPageSubdirective):
- """
- The page directive is used to create views that provide a single
- url or page.
-
- The page directive creates a new view class from a given template
- and/or class and registers it.
- """
-
-#
-# misc. directives
-#
-
-class IDefaultSkinDirective(Interface):
- """Sets the default browser skin
- """
-
- name = TextLine(
- title=u"Default skin name",
- description=u"Default skin name",
- required=True
- )
Copied: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests.py (from rev 103154, Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests/test_directives.py)
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests.py (rev 0)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/tests.py 2009-08-24 16:22:07 UTC (rev 103163)
@@ -0,0 +1,238 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""'browser' namespace directive tests
+
+$Id$
+"""
+
+import sys
+import os
+import unittest
+from cStringIO import StringIO
+
+from zope import component
+from zope.interface import Interface, implements, directlyProvides, providedBy
+
+import zope.security.management
+from zope.configuration.xmlconfig import xmlconfig, XMLConfig
+from zope.configuration.exceptions import ConfigurationError
+from zope.publisher.browser import TestRequest
+from zope.publisher.interfaces import IDefaultViewName
+from zope.publisher.interfaces.browser import IBrowserPublisher
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.interfaces.browser import IBrowserSkinType, IDefaultSkin
+from zope.security.proxy import removeSecurityProxy, ProxyFactory
+from zope.security.permission import Permission
+from zope.security.interfaces import IPermission
+from zope.testing.doctestunit import DocTestSuite
+from zope.traversing.adapters import DefaultTraversable
+from zope.traversing.interfaces import ITraversable
+
+import zope.publisher.defaultview
+import zope.app.publisher.browser
+from zope.component.testfiles.views import IC, V1, VZMI, R1, IV
+from zope.app.publisher.browser.fileresource import FileResource
+from zope.app.publisher.browser.i18nfileresource import I18nFileResource
+from zope.browsermenu.menu import getFirstMenuItem
+from zope.browsermenu.interfaces import IMenuItemType, IBrowserMenu
+from zope.app.testing import placelesssetup, ztapi
+
+tests_path = os.path.join(
+ os.path.dirname(zope.app.publisher.browser.__file__),
+ 'tests')
+
+template = """<configure
+ xmlns='http://namespaces.zope.org/zope'
+ xmlns:browser='http://namespaces.zope.org/browser'
+ i18n_domain='zope'>
+ %s
+ </configure>"""
+
+
+request = TestRequest()
+
+class V2(V1, object):
+
+ def action(self):
+ return self.action2()
+
+ def action2(self):
+ return "done"
+
+class VT(V1, object):
+ def publishTraverse(self, request, name):
+ try:
+ return int(name)
+ except:
+ return super(VT, self).publishTraverse(request, name)
+
+class Ob(object):
+ implements(IC)
+
+ob = Ob()
+
+class NCV(object):
+ "non callable view"
+
+ def __init__(self, context, request):
+ pass
+
+class CV(NCV):
+ "callable view"
+ def __call__(self):
+ pass
+
+
+class C_w_implements(NCV):
+ implements(Interface)
+
+ def index(self):
+ return self
+
+class ITestMenu(Interface):
+ """Test menu."""
+
+directlyProvides(ITestMenu, IMenuItemType)
+
+
+class ITestLayer(IBrowserRequest):
+ """Test Layer."""
+
+class ITestSkin(ITestLayer):
+ """Test Skin."""
+
+
+class MyResource(object):
+
+ def __init__(self, request):
+ self.request = request
+
+
+class Test(placelesssetup.PlacelessSetup, unittest.TestCase):
+
+ def setUp(self):
+ super(Test, self).setUp()
+ XMLConfig('meta.zcml', zope.app.publisher.browser)()
+ ztapi.provideAdapter(None, ITraversable, DefaultTraversable)
+
+ def testDefaultView(self):
+ self.assertEqual(
+ component.queryMultiAdapter((ob, request), IDefaultViewName),
+ None)
+
+ xmlconfig(StringIO(template % (
+ '''
+ <browser:defaultView
+ name="test"
+ for="zope.component.testfiles.views.IC" />
+ '''
+ )))
+
+ self.assertEqual(
+ zope.publisher.defaultview.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
+ name="test"
+ for="zope.component.testfiles.views.IC" />
+
+ <browser:defaultView
+ name="test2"
+ for="zope.component.testfiles.views.IC"
+ layer="
+ zope.app.publisher.browser.tests.ITestLayer"
+ />
+ '''
+ )))
+
+ 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.app.publisher.browser.tests.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', zope.component)()
+ xmlconfig(StringIO(template % (
+ '''
+ <interface
+ interface="
+ zope.app.publisher.browser.tests.ITestSkin"
+ type="zope.publisher.interfaces.browser.IBrowserSkinType"
+ name="Test Skin"
+ />
+ <browser:defaultSkin name="Test Skin" />
+ <browser:page
+ name="test"
+ class="zope.component.testfiles.views.VZMI"
+ layer="
+ zope.app.publisher.browser.tests.ITestLayer"
+ for="zope.component.testfiles.views.IC"
+ permission="zope.Public"
+ attribute="index"
+ />
+ <browser:page name="test"
+ class="zope.component.testfiles.views.V1"
+ for="zope.component.testfiles.views.IC"
+ permission="zope.Public"
+ attribute="index"
+ />
+ '''
+ )))
+
+ # 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.assert_(issubclass(v.__class__, VZMI))
+
+def test_suite():
+ return unittest.makeSuite(Test)
Modified: Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/viewmeta.py
===================================================================
--- Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/viewmeta.py 2009-08-24 15:58:56 UTC (rev 103162)
+++ Sandbox/nadako/zope.app.publisher/src/zope/app/publisher/browser/viewmeta.py 2009-08-24 16:22:07 UTC (rev 103163)
@@ -15,404 +15,16 @@
$Id$
"""
-import os
-
-from zope.component import queryMultiAdapter
-from zope.component.interface import provideInterface
-from zope.component.zcml import handler
-from zope.interface import implements, classImplements, Interface
-from zope.publisher.interfaces import NotFound
-from zope.security.checker import CheckerPublic, Checker, defineChecker
-from zope.configuration.exceptions import ConfigurationError
-from zope.publisher.interfaces.browser import IBrowserRequest
-from zope.publisher.interfaces.browser import IDefaultBrowserLayer
-from zope.publisher.interfaces.browser import IBrowserPublisher
-from zope.publisher.browser import BrowserView
-
-from zope.app.pagetemplate.simpleviewclass import SimpleViewClass
-from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
-from zope.browsermenu.metaconfigure import menuItemDirective
-
-# There are three cases we want to suport:
-#
-# Named view without pages (single-page view)
-#
-# <browser:page
-# for=".IContact.IContactInfo."
-# name="info.html"
-# template="info.pt"
-# class=".ContactInfoView."
-# permission="zope.View"
-# />
-#
-# Unnamed view with pages (multi-page view)
-#
-# <browser:pages
-# for=".IContact."
-# class=".ContactEditView."
-# permission="ZopeProducts.Contact.ManageContacts"
-# >
-#
-# <browser:page name="edit.html" template="edit.pt" />
-# <browser:page name="editAction.html" attribute="action" />
-# </browser:pages>
-#
-# Named view with pages (add view is a special case of this)
-#
-# <browser:view
-# name="ZopeProducts.Contact"
-# for="Zope.App.OFS.Container.IAdding."
-# class=".ContactAddView."
-# permission="ZopeProducts.Contact.ManageContacts"
-# >
-#
-# <browser:page name="add.html" template="add.pt" />
-# <browser:page name="action.html" attribute="action" />
-# </browser:view>
-
-# We'll also provide a convenience directive for add views:
-#
-# <browser:add
-# name="ZopeProducts.Contact"
-# class=".ContactAddView."
-# permission="ZopeProducts.Contact.ManageContacts"
-# >
-#
-# <browser:page name="add.html" template="add.pt" />
-# <browser:page name="action.html" attribute="action" />
-# </browser:view>
-
-# page
-
-def page(_context, name, permission, for_,
- layer=IDefaultBrowserLayer, template=None, class_=None,
- allowed_interface=None, allowed_attributes=None,
- attribute='__call__', menu=None, title=None,
- ):
- _handle_menu(_context, menu, title, [for_], name, permission, layer)
- required = {}
-
- permission = _handle_permission(_context, permission)
-
- if not (class_ or template):
- raise ConfigurationError("Must specify a class or template")
-
- if attribute != '__call__':
- if template:
- raise ConfigurationError(
- "Attribute and template cannot be used together.")
-
- if not class_:
- raise ConfigurationError(
- "A class must be provided if attribute is used")
-
- if template:
- template = os.path.abspath(str(_context.path(template)))
- if not os.path.isfile(template):
- raise ConfigurationError("No such file", template)
- required['__getitem__'] = permission
-
- # TODO: new __name__ attribute must be tested
- if class_:
- if attribute != '__call__':
- if not hasattr(class_, attribute):
- raise ConfigurationError(
- "The provided class doesn't have the specified attribute "
- )
- if template:
- # class and template
- new_class = SimpleViewClass(template, bases=(class_, ), name=name)
- else:
- if not hasattr(class_, 'browserDefault'):
- cdict = {
- 'browserDefault':
- lambda self, request: (getattr(self, attribute), ())
- }
- else:
- cdict = {}
-
- cdict['__name__'] = name
- cdict['__page_attribute__'] = attribute
- new_class = type(class_.__name__, (class_, simple,), cdict)
-
- if hasattr(class_, '__implements__'):
- classImplements(new_class, IBrowserPublisher)
-
- else:
- # template
- new_class = SimpleViewClass(template, name=name)
-
- for n in (attribute, 'browserDefault', '__call__', 'publishTraverse'):
- required[n] = permission
-
- _handle_allowed_interface(_context, allowed_interface, permission,
- required)
- _handle_allowed_attributes(_context, allowed_attributes, permission,
- required)
-
- _handle_for(_context, for_)
-
- defineChecker(new_class, Checker(required))
-
- _context.action(
- discriminator = ('view', for_, name, IBrowserRequest, layer),
- callable = handler,
- args = ('registerAdapter',
- new_class, (for_, layer), Interface, name, _context.info),
- )
-
-
-# pages, which are just a short-hand for multiple page directives.
-
-# Note that a class might want to access one of the defined
-# templates. If it does though, it should use getMultiAdapter.
-
-class pages(object):
-
- def __init__(self, _context, for_, permission,
- layer=IDefaultBrowserLayer, class_=None,
- allowed_interface=None, allowed_attributes=None,
- ):
- self.opts = dict(for_=for_, permission=permission,
- layer=layer, class_=class_,
- allowed_interface=allowed_interface,
- allowed_attributes=allowed_attributes,
- )
-
- def page(self, _context, name, attribute='__call__', template=None,
- menu=None, title=None):
- return page(_context,
- name=name,
- attribute=attribute,
- template=template,
- menu=menu, title=title,
- **(self.opts))
-
- def __call__(self):
- return ()
-
-# view (named view with pages)
-
-# This is a different case. We actually build a class with attributes
-# for all of the given pages.
-
-class view(object):
-
- default = None
-
- def __init__(self, _context, for_, permission,
- name='', layer=IDefaultBrowserLayer, class_=None,
- allowed_interface=None, allowed_attributes=None,
- menu=None, title=None, provides=Interface,
- ):
-
- _handle_menu(_context, menu, title, [for_], name, permission, layer)
-
- permission = _handle_permission(_context, permission)
-
- self.args = (_context, name, for_, permission, layer, class_,
- allowed_interface, allowed_attributes)
-
- self.pages = []
- self.menu = menu
- self.provides = provides
-
- def page(self, _context, name, attribute=None, template=None):
- if template:
- template = os.path.abspath(_context.path(template))
- if not os.path.isfile(template):
- raise ConfigurationError("No such file", template)
- else:
- if not attribute:
- raise ConfigurationError(
- "Must specify either a template or an attribute name")
-
- self.pages.append((name, attribute, template))
- return ()
-
- def defaultPage(self, _context, name):
- self.default = name
- return ()
-
- def __call__(self):
- (_context, name, for_, permission, layer, class_,
- allowed_interface, allowed_attributes) = self.args
-
- required = {}
-
- cdict = {}
- pages = {}
-
- for pname, attribute, template in self.pages:
-
- if template:
- cdict[pname] = ViewPageTemplateFile(template)
- if attribute and attribute != name:
- cdict[attribute] = cdict[pname]
- else:
- if not hasattr(class_, attribute):
- raise ConfigurationError("Undefined attribute",
- attribute)
-
- attribute = attribute or pname
- required[pname] = permission
-
- pages[pname] = attribute
-
- # This should go away, but noone seems to remember what to do. :-(
- if hasattr(class_, 'publishTraverse'):
-
- def publishTraverse(self, request, name,
- pages=pages, getattr=getattr):
-
- if name in pages:
- return getattr(self, pages[name])
- view = queryMultiAdapter((self, request), name=name)
- if view is not None:
- return view
-
- m = class_.publishTraverse.__get__(self)
- return m(request, name)
-
- else:
- def publishTraverse(self, request, name,
- pages=pages, getattr=getattr):
-
- if name in pages:
- return getattr(self, pages[name])
- view = queryMultiAdapter((self, request), name=name)
- if view is not None:
- return view
-
- raise NotFound(self, name, request)
-
- cdict['publishTraverse'] = publishTraverse
-
- if not hasattr(class_, 'browserDefault'):
- if self.default or self.pages:
- default = self.default or self.pages[0][0]
- cdict['browserDefault'] = (
- lambda self, request, default=default:
- (self, (default, ))
- )
- elif providesCallable(class_):
- cdict['browserDefault'] = (
- lambda self, request: (self, ())
- )
-
- if class_ is not None:
- bases = (class_, simple)
- else:
- bases = (simple,)
-
- try:
- cname = str(name)
- except:
- cname = "GeneratedClass"
-
- cdict['__name__'] = name
- newclass = type(cname, bases, cdict)
-
- for n in ('publishTraverse', 'browserDefault', '__call__'):
- required[n] = permission
-
- _handle_allowed_interface(_context, allowed_interface, permission,
- required)
- _handle_allowed_attributes(_context, allowed_attributes, permission,
- required)
- _handle_for(_context, for_)
-
- defineChecker(newclass, Checker(required))
-
- if self.provides is not None:
- _context.action(
- discriminator = None,
- callable = provideInterface,
- args = ('', self.provides)
- )
-
- _context.action(
- discriminator = ('view', (for_, layer), name, self.provides),
- callable = handler,
- args = ('registerAdapter',
- newclass, (for_, layer), self.provides, name,
- _context.info),
- )
-
-def _handle_menu(_context, menu, title, for_, name, permission,
- layer=IDefaultBrowserLayer):
-
- if menu or title:
- if not (menu and title):
- 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,
- permission=permission, layer=layer)
-
- return []
-
-def _handle_permission(_context, permission):
- if permission == 'zope.Public':
- permission = CheckerPublic
-
- return permission
-
-def _handle_allowed_interface(_context, allowed_interface, permission,
- required):
- # Allow access for all names defined by named interfaces
- if allowed_interface:
- for i in allowed_interface:
- _context.action(
- discriminator = None,
- callable = provideInterface,
- args = (None, i)
- )
-
- for name in i:
- required[name] = permission
-
-def _handle_allowed_attributes(_context, allowed_attributes, permission,
- required):
- # Allow access for all named attributes
- if allowed_attributes:
- for name in allowed_attributes:
- required[name] = permission
-
-def _handle_for(_context, for_):
- if for_ is not None:
- _context.action(
- discriminator = None,
- callable = provideInterface,
- args = ('', for_)
- )
-
-class simple(BrowserView):
- implements(IBrowserPublisher)
-
- def publishTraverse(self, request, name):
- raise NotFound(self, name, request)
-
- def __call__(self, *a, **k):
- # If a class doesn't provide it's own call, then get the attribute
- # given by the browser default.
-
- attr = self.__page_attribute__
- if attr == '__call__':
- raise AttributeError("__call__")
-
- meth = getattr(self, attr)
- return meth(*a, **k)
-
-def providesCallable(class_):
- if hasattr(class_, '__call__'):
- for c in class_.__mro__:
- if '__call__' in c.__dict__:
- return True
- return False
+# BBB imports
+from zope.browserpage.metaconfigure import (
+ page,
+ pages,
+ view,
+ _handle_menu,
+ _handle_permission,
+ _handle_allowed_interface,
+ _handle_allowed_attributes,
+ _handle_for,
+ simple,
+ providesCallable,
+)
More information about the Checkins
mailing list