[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