[Zope3-checkins] CVS: Zope3/src/zope/app/browser/utilities - __init__.py:1.2 add.pt:1.2 configure.zcml:1.2 content.py:1.2 edit.pt:1.2 permission_edit.pt:1.2 schema.py:1.2 traversal.py:1.2

Stephan Richter srichter at cosmos.phy.tufts.edu
Fri Aug 15 21:45:19 EDT 2003


Update of /cvs-repository/Zope3/src/zope/app/browser/utilities
In directory cvs.zope.org:/tmp/cvs-serv20171/app/browser/utilities

Added Files:
	__init__.py add.pt configure.zcml content.py edit.pt 
	permission_edit.pt schema.py traversal.py 
Log Message:
Merging dreamcatcher's TTW Schema branch:

1. Fixed Bug in adding that would cause infinite loops when the menu items
   action was not a valif view or factory id.

2. Extended adding to support more complex views. Until now we only 
   supported constructions like "+/AddView=id". Now you are able to say
   "+/AddView/More=id", which means that more information can be carried 
   in the URL. This can be used in many ways, including multi-page adding
   wizards. In my case I needed it to pass in the type of the TTW Schema-
   based Content Component.

3. Added Local Menus. This was a pain in the butt, but I think I got a 
   fairly nice model, where you can create local Menu Services, and Menus
   are simply named utilities. When active they are menus in the menu 
   service. This is very similar to the local interface service and TTW 
   Schema. 

4. Made some modifications to TTW Schema, cleaned up the code and moved
   the browser code and interfaces to the places they belong.

5. Added a Content Component Definition utility component, which takes a
   Schema and creates a content component for it, including permission
   settings and a menu entry. Currently the menu entry is always made to
   a local 'add_content' menu. I will change this and make it actually a
   screen, where the menu and title of the menu item can be chosen by the
   developer. Mmmh, should I add a factory for the definition as well, so
   that the content component is also available via python?

6. Added a Content Component Instance component that represents an 
   instance od a Content Component Definition. You will never directly 
   encounter this component, since it is automatically used by the adding
   code of the Content Component Definition.

7. Cleanups by both dreamcatcher and myself.

That's it. For more details see the branch checkin messages. I now consider
the dreamcatcher-ttwschema-branch closed.


=== Zope3/src/zope/app/browser/utilities/__init__.py 1.1 => 1.2 ===


=== Zope3/src/zope/app/browser/utilities/add.pt 1.1 => 1.2 ===
--- /dev/null	Fri Aug 15 20:45:17 2003
+++ Zope3/src/zope/app/browser/utilities/add.pt	Fri Aug 15 20:43:11 2003
@@ -0,0 +1,51 @@
+<html metal:use-macro="views/standard_macros/dialog">
+<body>
+<div metal:fill-slot="body">
+
+  <form action="action.html" method="post">
+    <table class="TypeListing" cellpadding="3">
+
+      <caption i18n:translate="">Add Content</caption>
+
+      <tbody tal:define="infos view/addingInfo">
+
+        <tr tal:repeat="info infos">
+
+          <td class="Selector">
+            <input type="radio" name="type_name"
+                   tal:attributes="value   info/action;
+                                   id      info/action;
+                                   checked python:len(infos)==1" />
+          </td>
+
+          <td class="TypeName">
+            <label style="font-weight: bold;"
+                   tal:attributes="for info/action">
+              <span tal:replace="info/title" >Folder</span>
+            </label>
+            <div class="TypeDescription" tal:content="info/description">
+              Folders are generic containers for content, including other
+              folders.
+            </div>
+          </td>
+        </tr>
+
+      <tr>
+        <td><br /></td>
+        <td>
+            <input type="text" name="id"
+                   tal:condition="view/namesAccepted"
+                   tal:attributes="value request/id | nothing" />
+            <input type="submit" value=" Add " 
+                   i18n:attributes="value add-button" />
+        </td>
+      </tr>
+
+      </tbody>
+
+    </table>
+  </form>
+
+</div>
+</body>
+</html>


=== Zope3/src/zope/app/browser/utilities/configure.zcml 1.1 => 1.2 ===
--- /dev/null	Fri Aug 15 20:45:17 2003
+++ Zope3/src/zope/app/browser/utilities/configure.zcml	Fri Aug 15 20:43:11 2003
@@ -0,0 +1,205 @@
+<configure
+  xmlns:zope="http://namespaces.zope.org/zope"
+  xmlns="http://namespaces.zope.org/browser">
+
+<!-- Mutable Schema -->
+
+  <menu
+      id="add_schema_field"
+      title="Menu of Fields to be added to a schema."/>
+
+  <view
+      name="+"
+      for="zope.app.interfaces.utilities.schema.IMutableSchema"
+      class="zope.app.utilities.schema.SchemaAdding"
+      permission="zope.ManageContent"
+      allowed_attributes="addingInfo"
+      menu="zmi_actions" title="Add">
+
+    <page name="index.html"  template="add.pt" />
+    <page name="action.html" attribute="action" />
+
+  </view>
+
+  <addform
+      label="New Mutable Schema Registration"
+      for="zope.app.interfaces.utilities.schema.ISchemaUtility"
+      name="addRegistration.html"
+      schema="zope.app.interfaces.services.utility.IUtilityRegistration"
+      class="zope.app.browser.services.utility.AddRegistration"
+      permission="zope.ManageServices"
+      content_factory="zope.app.utilities.schema.SchemaRegistration"
+      arguments="name interface componentPath"
+      set_after_add="status"
+      fields="name interface componentPath permission status" />
+
+
+  <!-- Menu entry for "add component" menu -->
+  <menuItem
+      for="zope.app.interfaces.container.IAdding"
+      menu="add_component"
+      action="zope.app.utilities.schema.SchemaUtility"
+      title="Mutable Schema"
+      description="A Persistent Schema that can be edited through the web"
+      permission="zope.ManageServices"
+      />
+
+  <!-- Menu entry for "add utility" menu -->
+  <menuItem
+      for="zope.app.interfaces.container.IAdding"
+      menu="add_utility"
+      action="zope.app.utilities.schema.SchemaUtility"
+      title="Mutable Schema"
+      description="A Persistent Schema that can be edited through the web"
+      permission="zope.ManageServices"
+      />
+
+
+  <defaultView
+      for="zope.app.interfaces.utilities.schema.IMutableSchema"
+      name="editschema.html" />
+
+  <page
+      name="editschema.html"
+      menu="zmi_views" title="Edit Schema"
+      for="zope.app.interfaces.utilities.schema.IMutableSchema"
+      permission="zope.ManageServices"
+      class="zope.app.browser.utilities.schema.EditSchema"
+      attribute="edit"
+   />
+
+  <!-- Widgets for the MutableSchemaField -->
+
+  <page
+      class="zope.app.browser.component.interfacewidget.InterfaceWidget"
+      for="zope.app.interfaces.utilities.schema.IMutableSchemaField"
+      name="edit"
+      permission="zope.Public" />
+
+  <page
+      class="zope.app.browser.component.interfacewidget.InterfaceDisplayWidget"
+      for="zope.app.interfaces.utilities.schema.IMutableSchemaField"
+      name="display"
+      permission="zope.Public" />
+
+  <page
+      class="zope.app.browser.component.interfacewidget.MultiInterfaceWidget"
+      for="zope.app.interfaces.utilities.schema.IMutableSchemasField"
+      name="edit"
+      permission="zope.Public" />
+
+  <page
+      class="
+      zope.app.browser.component.interfacewidget.MultiInterfaceDisplayWidget"
+      for="zope.app.interfaces.utilities.schema.IMutableSchemasField"
+      name="display"
+      permission="zope.Public" />
+
+  <editform
+     schema="zope.app.utilities.interfaces.IMutableSchemaContent"
+     name="setschema.html"
+     label="Set Schema"
+     permission="zope.ManageContent"
+     menu="zmi_views" title="Set Schema" />
+
+  <!-- Register a browser-specific traverser -->
+
+  <page
+      name="_traverse"
+      for="zope.app.interfaces.utilities.schema.IMutableSchema"
+      class=".traversal.SchemaFieldTraverser"
+      permission="zope.Public" />
+
+
+<!-- Content Component Definition -->
+
+  <addform
+      label="Content Component Definition Registration"
+      for= "zope.app.interfaces.utilities.content.IContentComponentDefinition"
+      name="addRegistration.html"
+      schema="zope.app.interfaces.services.utility.IUtilityRegistration"
+      class="zope.app.browser.services.utility.AddRegistration"
+      permission="zope.ManageServices"
+      content_factory="
+            zope.app.utilities.content.ContentComponentDefinitionRegistration"
+      arguments="name interface componentPath"
+      set_after_add="status"
+      fields="name interface componentPath permission status" />
+
+
+  <!-- Menu entry for "add component" menu -->
+  <menuItem
+      for="zope.app.interfaces.container.IAdding"
+      menu="add_component"
+      action="utility.ContentComponentDefinition"
+      title="Content Component Definition"
+      description="A Persistent Content Component Definition"
+      permission="zope.ManageServices"
+      />
+
+  <!-- Menu entry for "add utility" menu -->
+  <menuItem
+      for="zope.app.interfaces.container.IAdding"
+      menu="add_utility"
+      action="utility.ContentComponentDefinition"
+      title="Content Component Definition"
+      description="A Persistent Content Component Definition"
+      permission="zope.ManageServices"
+      />
+
+  <editform
+      for="zope.app.interfaces.utilities.content.IContentComponentDefinition"
+      schema="zope.app.interfaces.utilities.content.IContentComponentDefinition"
+      name="edit.html"
+      fields="schema"
+      menu="zmi_views" title="Edit"
+      permission="zope.ManageContent"/>
+
+  <editform
+      for="zope.app.interfaces.utilities.content.IContentComponentDefinition"
+      schema="zope.app.interfaces.utilities.content.IContentComponentDefinition"
+      name="editpermissions.html"
+      template="permission_edit.pt"
+      class=".content.ContentComponentPermissionEdit"
+      menu="zmi_views" title="Define Permissions"
+      permission="zope.ManageContent"/>
+
+  <defaultView
+      for="zope.app.interfaces.utilities.content.IContentComponentDefinition"
+      name="edit.html" />
+
+
+<!-- Content Component Instance -->
+
+  <page
+      name="AddContentComponent"
+      for="zope.app.interfaces.container.IAdding"
+      permission="zope.ManageContent"
+      class=".content.AddContentComponentInstanceView"
+      attribute="generated_form" />
+
+  <page
+      name="edit.html"
+      menu="zmi_views" title="Edit"
+      for="zope.app.interfaces.utilities.content.IContentComponentInstance"
+      permission="zope.ManageContent"
+      class=".content.EditContentComponentInstanceView"
+      attribute="generated_form" />
+
+  <!-- Directives to test the Content Component Instance -->
+  <addform
+      label="New Content Component Instance"
+      name="AddDirectContentComponent"
+      schema="zope.app.interfaces.utilities.content.IContentComponentInstance"
+      permission="zope.ManageContent"
+      content_factory="zope.app.utilities.content.ContentComponentInstance"
+      arguments="__name__ __schema__"
+      fields="__name__ __schema__"
+      menu="add_content" title="Schema-based Content"/>
+
+  <zope:adapter
+      factory=".traversal.SchemaFieldTraversable"
+      provides="zope.app.interfaces.traversing.ITraversable"
+      for="zope.app.interfaces.utilities.schema.IMutableSchema" />
+
+</configure>


=== Zope3/src/zope/app/browser/utilities/content.py 1.1 => 1.2 ===
--- /dev/null	Fri Aug 15 20:45:17 2003
+++ Zope3/src/zope/app/browser/utilities/content.py	Fri Aug 15 20:43:11 2003
@@ -0,0 +1,153 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""Content Component Views
+
+$Id$
+"""
+from zope.app import zapi
+from zope.app.browser.form.add import AddView
+from zope.app.browser.form.editview import EditView
+from zope.app.browser.form.submit import Update
+from zope.app.form.utility import setUpWidget
+from zope.app.interfaces.utilities.content import IContentComponentDefinition
+from zope.app.security.permission import PermissionField
+from zope.app.services.servicenames import Utilities
+from zope.app.utilities.content import ContentComponentInstance
+from zope.component.exceptions import ComponentLookupError
+from zope.interface import implements
+from zope.publisher.interfaces import IPublishTraverse
+from zope.schema import getFieldNamesInOrder, getFieldsInOrder
+from zope.security.checker import CheckerPublic
+from zope.security.proxy import trustedRemoveSecurityProxy
+
+class ContentComponentPermissionEdit(EditView):
+
+    def __init__(self, context, request):
+        super(ContentComponentPermissionEdit, self).__init__(context, request)
+        self.buildPermissionWidgets()
+
+    def buildPermissionWidgets(self):
+        schema = self.context.schema
+        for name, field in getFieldsInOrder(schema):
+            # Try to get current settings
+            if self.context.permissions.has_key(name):
+                get_perm, set_perm = self.context.permissions[name]
+            else:
+                get_perm, set_perm = None, None
+
+            # Create the Accessor Permission Widget for this field
+            permField = PermissionField(
+                __name__=name+'_get_perm',
+                title=u"Accessor Permission",
+                default=CheckerPublic,
+                required=False)
+            setUpWidget(self, name+'_get_perm', permField, value=get_perm)
+
+            # Create the Mutator Permission Widget for this field
+            permField = PermissionField(
+                __name__=name+'_set_perm',
+                title=u"Mutator Permission",
+                default=CheckerPublic,
+                required=False)
+            setUpWidget(self, name+'_set_perm', permField, value=set_perm)
+
+    def update(self):
+        status = ''
+
+        if Update in self.request:
+            status = super(ContentComponentPermissionEdit, self).update()
+            self.buildPermissionWidgets()
+        elif 'CHANGE' in self.request:
+            schema = self.context.schema
+            perms = trustedRemoveSecurityProxy(self.context.permissions)
+            for name, field in getFieldsInOrder(schema):
+                getPerm = getattr(self, name+'_get_perm_widget').getData()
+                setPerm = getattr(self, name+'_set_perm_widget').getData()
+                perms[name] = (getPerm, setPerm)
+            status = 'Fields permissions mapping updated.'
+
+        return status
+
+    def getPermissionWidgets(self):
+        schema = self.context.schema
+        info = []
+        for name, field in getFieldsInOrder(schema):
+            field = trustedRemoveSecurityProxy(field)
+            info.append(
+                {'fieldName': name,
+                 'fieldTitle': field.title,
+                 'getter': getattr(self, name+'_get_perm_widget'),
+                 'setter': getattr(self, name+'_set_perm_widget')} )
+        return info
+
+
+class AddContentComponentInstanceView(AddView):
+
+    implements(IPublishTraverse)
+
+    def __init__(self, context, request):
+        self.context = context
+        self.request = request
+
+    def publishTraverse(self, request, name):
+        """See zope.app.interfaces.container.IAdding"""
+        if '=' in name:
+            type_name, content_name = name.split("=", 1)
+            self.context.contentName = content_name
+
+        utilities = zapi.getService(self.context, Utilities)
+        matching = utilities.getRegisteredMatching(IContentComponentDefinition,
+                                                   type_name)
+        if not (matching and matching[0][2].active()):
+            raise ComponentLookupError, \
+                  "No Content Component Definition named '%s' found" %type_name
+
+        self.definition = matching[0][2].active().getComponent()
+        self.schema = self.definition.schema
+        self.label = 'Add %s' %self.definition.name
+        super(AddContentComponentInstanceView, self).__init__(self.context,
+                                                              request)
+
+        return self.generated_form
+
+    def createAndAdd(self, data):
+        """Create a Content Component Instance and add it to the container."""
+        content = ContentComponentInstance(self.definition.name,
+                                           self.definition.schema,
+                                           self.definition.permissions)
+        errors = []
+        for name, value in data.items():
+            field = self.schema[name]
+            try:
+                field.set(content, data[name])
+            except ValidationError:
+                errors.append(sys.exc_info()[1])
+
+        content = self.add(content)
+
+        if errors:
+            raise WidgetsError(*errors)
+
+        return content
+
+
+class EditContentComponentInstanceView(EditView):
+
+    def __init__(self, context, request):
+        self.schema = context.getSchema()
+        self.label = 'Edit %s' %context.__name__
+        super(EditContentComponentInstanceView, self).__init__(context,
+                                                               request)
+
+


=== Zope3/src/zope/app/browser/utilities/edit.pt 1.1 => 1.2 ===
--- /dev/null	Fri Aug 15 20:45:18 2003
+++ Zope3/src/zope/app/browser/utilities/edit.pt	Fri Aug 15 20:43:11 2003
@@ -0,0 +1,80 @@
+<html metal:use-macro="views/standard_macros/page">
+  <body>
+  <div metal:fill-slot="body">
+
+  <div metal:define-macro="body">
+
+    <h3 i18n:translate="">
+      Schema Name: 
+      <span tal:content="view/name" i18n:name="schema_name"/>
+    </h3>
+
+    <form action="." tal:attributes="action request/URL" method="POST"
+          enctype="multipart/form-data">
+
+    <p tal:define="status view/update"
+       tal:condition="status"
+       tal:content="status" />
+
+    <p tal:condition="view/errors" i18n:translate="">
+           There are  <strong tal:content="python:len(view.errors)"
+                              i18n:name="num_errors">6</strong> input errors.
+    </p>
+
+    <tal:block repeat="error view/errors">
+       <div class="error" tal:content="error">error</div>
+    </tal:block>
+
+    <div metal:define-macro="formbody">
+
+      <table id="sortable" class="listing" summary="Content listing"
+             i18n:attributes="summary">
+
+        <thead>
+          <tr>
+            <th>&nbsp;</th>
+            <th i18n:translate="">Name</th>
+            <th i18n:translate="">Type</th>
+            <th i18n:translate="">Title</th>
+            <th i18n:translate="">Required</th>
+            <th i18n:translate="">Read-Only</th>
+          </tr>
+        </thead>
+
+        <tbody>
+
+        <tr tal:repeat="row view/fields">
+          <td><input type="checkbox" name="ids:list"
+                     value=""
+                     tal:attributes="value row/name" /></td>
+          <td><a href="#"
+                 tal:attributes="href string:${request/URL/-1}/${row/name}/@@edit.html"
+                 tal:content="row/name">Name</a></td>
+          <td tal:content="row/type">Type</td>
+          <tal:block define="field row/field">
+          <td tal:content="field/title">Title</td>
+          <td tal:content="field/required">Required</td>
+          <td tal:content="field/readonly">Read-Only</td>
+          </tal:block>
+        </tr>
+
+        </tbody>
+      </table>
+
+      </div>
+
+      <div class="row">
+        <div class="controls">
+          <input type="submit" name="DELETE" value="Delete"
+              i18n:attributes="value delete-field-button" />
+        </div>
+      </div>
+
+  </form>
+
+  </div>
+
+  </div>
+  </body>
+
+</html>


=== Zope3/src/zope/app/browser/utilities/permission_edit.pt 1.1 => 1.2 ===
--- /dev/null	Fri Aug 15 20:45:18 2003
+++ Zope3/src/zope/app/browser/utilities/permission_edit.pt	Fri Aug 15 20:43:11 2003
@@ -0,0 +1,48 @@
+<html metal:use-macro="views/standard_macros/page">
+<body>
+<div metal:fill-slot="body">
+
+  <p tal:define="status view/update"
+     tal:condition="status"
+     tal:content="status" />
+
+  <form action="./@@edit.html"
+        tal:attributes="action request/URL" method="POST">
+
+    <tal:block define="widgets view/getPermissionWidgets"
+               condition="widgets">
+      <h4 i18n:translate="">Map permissions to Schema fields</h4>
+
+      <tal:block repeat="widget widgets">
+        <h5 tal:content="string:${widget/fieldTitle} (${widget/fieldName})">
+          FieldName (Field Title)
+        </h5>
+        <div class="row" tal:replace="structure widget/getter/row">
+          <div class="label" i18n:translate="">Get Permission</div>
+          <div class="field">
+
+          </div>
+        </div>
+        <div class="row" tal:replace="structure widget/setter/row">
+          <div class="label" i18n:translate="">Set Permission</div>
+          <div class="field">
+
+          </div>
+        </div>
+        <br />
+      </tal:block>
+      <div class="row">
+        <div class="controls" style="width: 100%">
+          <input type="submit" value="Refresh"
+                 i18n:attributes="value refresh-button" />
+          <input type="submit" value="Change" name="CHANGE"
+                 i18n:attributes="value change-button" />
+         </div>
+      </div>
+    </tal:block>
+
+  </form>
+
+</div>
+</body>
+</html>
\ No newline at end of file


=== Zope3/src/zope/app/browser/utilities/schema.py 1.1 => 1.2 ===
--- /dev/null	Fri Aug 15 20:45:18 2003
+++ Zope3/src/zope/app/browser/utilities/schema.py	Fri Aug 15 20:43:11 2003
@@ -0,0 +1,75 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""Mutable Schema (as Utility) Views
+
+$Id$
+"""
+from zope.app import zapi
+from zope.app.browser.form.editview import EditView
+from zope.app.form.utility import setUpEditWidgets
+from zope.app.i18n import ZopeMessageIDFactory as _
+from zope.app.interfaces.utilities.schema import IMutableSchema
+from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
+from zope.app.security.permission import PermissionField
+from zope.app.utilities.schema import SchemaAdding
+from zope.publisher.browser import BrowserView
+from zope.schema import getFieldNamesInOrder, getFieldsInOrder
+
+class EditSchema(BrowserView):
+
+    edit = ViewPageTemplateFile('edit.pt')
+    errors = ()
+    update_status = None
+
+    def name(self):
+        return self.context.getName()
+
+    def fieldNames(self):
+        return getFieldNamesInOrder(self.context)
+
+    def fields(self):
+        return [{'name':name,
+                 'field':zapi.ContextWrapper(field, self.context),
+                 'type':field.__class__.__name__}
+                for name, field in getFieldsInOrder(self.context)]
+
+    def update(self):
+        status = ''
+        container = zapi.getAdapter(self.context, IMutableSchema)
+
+        if 'DELETE' in self.request:
+            if not 'ids' in self.request:
+                self.errors = (_("Must select a field to delete"),)
+                status = _("An error occured.")
+            for id in self.request.get('ids', []):
+                container.removeField(id)
+
+        self.update_status = status
+        return status
+
+
+class EditMutableSchema(EditView):
+
+    def _get_schema(self):
+        return self.context.mutableschema
+
+    schema = property(_get_schema)
+
+    def _setUpWidgets(self):
+        adapted = zapi.getAdapter(self.context, self.schema)
+        if adapted is not self.context:
+            adapted = zapi.ContextWrapper(adapted, self.context,
+                                          name=_('(adapted)'))
+        setUpEditWidgets(self, self.schema, names=self.fieldNames,
+                         content=self.adapted)


=== Zope3/src/zope/app/browser/utilities/traversal.py 1.1 => 1.2 ===
--- /dev/null	Fri Aug 15 20:45:19 2003
+++ Zope3/src/zope/app/browser/utilities/traversal.py	Fri Aug 15 20:43:11 2003
@@ -0,0 +1,80 @@
+##############################################################################
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+##############################################################################
+"""Specific HTTP
+
+$Id$
+"""
+from zope.interface import implements
+from zope.component import getDefaultViewName, queryView
+from zope.publisher.interfaces import IPublishTraverse
+from zope.app.interfaces.utilities.schema import IMutableSchema
+
+from zope.exceptions import NotFoundError
+from zope.app.traversing import getParent
+
+from zope.proxy import removeAllProxies
+from zope.app.context import ContextWrapper
+
+from zope.app.interfaces.traversing import ITraversable
+from zope.app.traversing.namespace import UnexpectedParameters
+
+_marker = object()
+
+class SchemaFieldTraverser:
+
+    implements(IPublishTraverse)
+    __used_for__ = IMutableSchema
+
+    def __init__(self, context, request):
+        self.context = context
+        self.request = request
+
+    def publishTraverse(self, request, name):
+        subob = self.context.get(name, None)
+
+        # XXX: Check that subobj has self.context as parent!
+        if subob is None:
+
+            view = queryView(self.context, name, request)
+            if view is not None:
+                return view
+
+            raise NotFoundError(self.context, name, request)
+
+        subob = removeAllProxies(subob)
+        return ContextWrapper(subob, self.context, name=name)
+
+    def browserDefault(self, request):
+        c = self.context
+        view_name = getDefaultViewName(c, request)
+        view_uri = "@@%s" % view_name
+        return c, (view_uri,)
+
+class SchemaFieldTraversable:
+    """Traverses Schema Fields.
+    """
+
+    implements(ITraversable)
+    __used_for__ = IMutableSchema
+
+    def __init__(self, context):
+        self._context = context
+
+    def traverse(self, name, parameters, original_name, furtherPath):
+        if parameters:
+            raise UnexpectedParameters(parameters)
+
+        subobj = self._context.get(name, _marker)
+        if subobj is _marker:
+            raise NotFoundError, original_name
+
+        return subobj




More information about the Zope3-Checkins mailing list