[Zope3-checkins] CVS: Zope3/src/zope/app/browser/form - display.pt:1.1 schemadisplay.py:1.1 meta.zcml:1.9

Fred L. Drake, Jr. fred@zope.com
Wed, 16 Apr 2003 17:56:04 -0400


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

Modified Files:
	meta.zcml 
Added Files:
	display.pt schemadisplay.py 
Log Message:
New ZCML directive, browser:schemadisplay, provides schema-based views that
display content fields without allowing the user to edit them.


=== Added File Zope3/src/zope/app/browser/form/display.pt ===
<html metal:use-macro="views/standard_macros/page">
<body>
<div metal:fill-slot="body">
<div metal:define-macro="body">

  <div metal:define-macro="formbody">

    <h3 tal:condition="view/label"
        tal:content="view/label"
        metal:define-slot="heading"
        >Display something</h3>

    <div metal:define-slot="extra_info" tal:replace="nothing">
    </div>

    <div class="row"
         metal:define-slot="extra_top" tal:replace="nothing">
        <div class="label">Extra top</div>
        <div class="field"><input type="text" style="width:100%" /></div>
    </div>
    <div class="row"
         metal:define-macro="widget_rows" tal:repeat="widget view/widgets"
         tal:content="structure widget/row">
        <div class="label">Name</div>
        <div class="field"><input type="text" style="width:100%" /></div>
    </div>
    <div class="row"
         metal:define-slot="extra_bottom" tal:replace="nothing">
        <div class="label">Extra bottom</div>
        <div class="field"><input type="text" style="width:100%" /></div>
    </div>

  </div>

</div>
</div>
</body>
</html>


=== Added File Zope3/src/zope/app/browser/form/schemadisplay.py ===
##############################################################################
#
# 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.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.
#
##############################################################################
"""\
Support for display-only pages based on schema.

$Id: schemadisplay.py,v 1.1 2003/04/16 21:56:03 fdrake Exp $
"""

from zope.schema import getFieldNamesInOrder

from zope.configuration.action import Action
from zope.proxy.context import ContextWrapper
from zope.publisher.interfaces.browser import IBrowserPresentation
from zope.publisher.browser import BrowserView
from zope.security.checker import defineChecker, NamesChecker
from zope.component.view import provideView
from zope.component import getAdapter

from zope.app.interfaces.form import WidgetsError
from zope.app.component.metaconfigure import resolveInterface
from zope.app.form.utility import setUpDisplayWidgets, getWidgetsData
from zope.app.browser.form.submit import Update
from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
from zope.app.pagetemplate.simpleviewclass import SimpleViewClass

from zope.app.publisher.browser.globalbrowsermenuservice \
     import menuItemDirective, globalBrowserMenuService

# XXX perhaps a little too intimate?
from zope.app.browser.form.editview import normalize


class DisplayView(BrowserView):
    """Simple display-view base class.

    Subclasses should provide a schema attribute defining the schema
    to be displayed.
    """

    errors = ()
    update_status = ''
    label = ''

    # Fall-back field names computes from schema
    fieldNames = property(lambda self: getFieldNamesInOrder(self.schema))

    def __init__(self, context, request):
        super(DisplayView, self).__init__(context, request)
        self._setUpWidgets()

    def _setUpWidgets(self):
        adapted = getAdapter(self.context, self.schema)
        if adapted is not self.context:
            adapted = ContextWrapper(adapted, self.context, name='(adapted)')
        self.adapted = adapted
        setUpDisplayWidgets(self, self.schema, names=self.fieldNames,
                            content=adapted)

    def setPrefix(self, prefix):
        for widget in self.widgets():
            widget.setPrefix(prefix)

    def widgets(self):
        return [getattr(self, name)
                for name in self.fieldNames]


def DisplayViewFactory(name, schema, label, permission, layer,
                       template, default_template, bases, for_, fields,
                       fulledit_path=None, fulledit_label=None, menu=u'',
                       usage=u''):
    # XXX What about the __implements__ of the bases?
    class_ = SimpleViewClass(template, used_for=schema, bases=bases)
    class_.schema = schema
    class_.label = label
    class_.fieldNames = fields
    class_.fulledit_path = fulledit_path
    if fulledit_path and (fulledit_label is None):
        fulledit_label = "Full display"
    class_.fulledit_label = fulledit_label
    class_.generated_form = ViewPageTemplateFile(default_template)
    class_.usage = usage or (
        menu and globalBrowserMenuService.getMenuUsage(menu)
        )
    defineChecker(class_,
                  NamesChecker(("__call__", "__getitem__", "browserDefault"),
                               permission))
    provideView(for_, name, IBrowserPresentation, class_, layer)


def display(_context, name, schema, permission, label='',
            layer="default",
            class_=None, for_=None,
            template=None, omit=None, fields=None,
            menu=None, title='Display', usage=u''):
    actions = []
    if menu:
        actions = menuItemDirective(
            _context, menu, for_ or schema, '@@' + name, title,
            permission=permission)

    schema, for_, bases, template, fields = normalize(
        _context, schema, for_, class_, template, 'display.pt', fields, omit,
        DisplayView)

    actions.append(Action(
        discriminator=('view', for_, name, IBrowserPresentation, layer),
        callable=DisplayViewFactory,
        args=(name, schema, label, permission, layer, template, 'display.pt',
              bases, for_, fields, menu, usage)))
    return actions


=== Zope3/src/zope/app/browser/form/meta.zcml 1.8 => 1.9 ===
--- Zope3/src/zope/app/browser/form/meta.zcml:1.8	Fri Apr  4 09:57:36 2003
+++ Zope3/src/zope/app/browser/form/meta.zcml	Wed Apr 16 17:56:03 2003
@@ -7,7 +7,7 @@
       <description>
         Define an automatically generated edit form
 
-        The editForm directive creates and register's a view for
+        The editform directive creates and register's a view for
         editing an object based on a schema.
       </description>
 
@@ -248,6 +248,102 @@
           the menu in the page directive, rather than having to give a
           separate menuItem directive.
           </description>
+        </attribute>
+
+      </directive>
+
+    <directive name="schemadisplay" handler=".schemadisplay.display">
+
+      <description>
+        Define an automatically generated display form.
+
+        The schemadisplay directive creates and register's a view for
+        displaying an object based on a schema.
+      </description>
+
+      <attribute name="name" required="yes">
+        <description>
+        The name of the generated display view.
+        </description>
+        </attribute>
+
+      <attribute name="schema" required="yes">
+        <description>
+        The schema from which the display form is generated.
+
+        A schema is an interface that includes fields.
+        </description>
+        </attribute>
+
+      <attribute name="label" required="no">
+        <description>
+        A label to be used as the heading for the form.
+        </description>
+        </attribute>
+
+      <attribute name="for" required="no">
+        <description>
+        The interface this page (view) applies to. 
+
+        The view will be for all objects that implement this interface.
+
+        The schema is used if the for attribute is not specified.
+
+        If the for attribute is specified, then the objects views must
+        implement or be adaptable to the schema.
+        </description>
+        </attribute>
+
+      <attribute name="layer" required="no">
+        <description>
+        The layer the view is in. 
+
+        A skin is composed of layers. It is common to put skin specific
+        views in a layer named after the skin. If the 'layer' attribute
+        is not supplied, it defaults to 'default'. 
+        </description>
+        </attribute>
+
+      <attribute name="permission" required="yes">
+        <description>
+        The permission needed to use the view. 
+        </description>
+        </attribute>
+
+      <attribute name="template" required="no">
+        <description>
+        An alternate template to use for the display form.
+
+        XXX Need to document how to extend the default.
+        </description>
+        </attribute>
+
+      <attribute name="class" required="no">
+        <description>
+        A class to provide custom widget definitions or methods to be
+        used by a custom template.
+
+        This class is used as a mix-in class. As a result, it needn't
+        subclass any special classes, such as BrowserView.
+        </description>
+        </attribute>
+
+      <attribute name="menu" required="no">
+        <description>
+        The browser menu to include the display form in.
+
+        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.
+        </description>
+        </attribute>
+
+      <attribute name="title" required="no">
+        <description>
+        The browser menu label for the display form
+
+        This attribute defaults to "Display".
+        </description>
         </attribute>
 
       </directive>