[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/Formulator - Errors.py:1.1.2.1 Errors.pyc:1.1.2.1 Form.py:1.1.2.1 Form.pyc:1.1.2.1 FormulatorProposal.stx:1.1.2.1 FormulatorProposal2.stx:1.1.2.1 __init__.py:1.1.2.1 __init__.pyc:1.1.2.1

Stephan Richter srichter@cbu.edu
Fri, 25 Jan 2002 09:11:07 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/App/Formulator
In directory cvs.zope.org:/tmp/cvs-serv20682/Formulator

Added Files:
      Tag: Zope-3x-branch
	Errors.py Errors.pyc Form.py Form.pyc FormulatorProposal.stx 
	FormulatorProposal2.stx __init__.py __init__.pyc 
Log Message:
- Initial check-in of the Formulator code
- Even though not everything works (specifically the widgets are in bad 
  shape), I am checking that stuff in, so that Jim, Martijn F. and I can
  better work together.
- The FileEdit screen (which will be checked in in a minute) uses already
  formulator.
- The validators are closed to finished.
- I think we have to rethink some of the design, simply because it is too
  hard right now to create a field and a view for a property, even though
  I provided already some handy methods. However Formulator does not 
  depend on Property-driven content objects.
- Please contact me (srichter@cbu.edu) or the Zope3 mailining list to 
  discuss issues and design.


=== Added File Zope3/lib/python/Zope/App/Formulator/Errors.py ===
##############################################################################
#
# Copyright (c) 2001 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
# 
##############################################################################
"""
Revision information: $Id: Errors.py,v 1.1.2.1 2002/01/25 14:11:06 srichter Exp $

Exception Classes for Formulator
"""

# These classes are placed here so that they can be imported into TTW Python
# scripts. To do so, add the following line to your Py script:
# from Products.Formulator.Errors import ValidationError, FormValidationError


class FormValidationError(Exception):

    def __init__(self, errors, result):
        Exception.__init__(self, "Form Validation Error")
        self.errors = errors
        self.result = result
        

class ValidationError(Exception):
    
    def __init__(self, errorKey, field):
        Exception.__init__(self, errorKey)
        self.errorKey = errorKey
        self.fieldId = field.id
        self.field = field
        self.errorText = field.getErrorMessage(errorKey)



=== Added File Zope3/lib/python/Zope/App/Formulator/Errors.pyc ===
-í
ôfQ<c       sB     d  Z    d e f d „  ƒ  YZ   d e f d „  ƒ  YZ d S(   s@   
Revision information: $Id: Errors.pyc,v 1.1.2.1 2002/01/25 14:11:06 srichter Exp $

Exception Classes for Formulator
s   FormValidationErrorc      s     d „  Z  RS(   Nc    s2     t  i |  d ƒ  | |  _  | |  _ d  S(   Ns   Form Validation Error(   s	   Exceptions   __init__s   selfs   errorss   result(   s   selfs   errorss   result(    (    s3   /opt/Zope3/lib/python/Zope/App/Formulator/Errors.pys   __init__ s   (   s   __init__(    (    (    s3   /opt/Zope3/lib/python/Zope/App/Formulator/Errors.pys   FormValidationError s   s   ValidationErrorc      s     " d „  Z  RS(   Nc    sV   " # t  i |  | ƒ $ | |  _ % | i |  _ & | |  _ ' | i | ƒ |  _ d  S(   N(	   s	   Exceptions   __init__s   selfs   errorKeys   fields   ids   fieldIds   getErrorMessages	   errorText(   s   selfs   errorKeys   field(    (    s3   /opt/Zope3/lib/python/Zope/App/Formulator/Errors.pys   __init__" s
   (   s   __init__(    (    (    s3   /opt/Zope3/lib/python/Zope/App/Formulator/Errors.pys   ValidationError  s   N(   s   __doc__s	   Exceptions   FormValidationErrors   ValidationError(   s   FormValidationErrors   ValidationError(    (    s3   /opt/Zope3/lib/python/Zope/App/Formulator/Errors.pys   ? s   

=== Added File Zope3/lib/python/Zope/App/Formulator/Form.py ===
##############################################################################
#
# Copyright (c) 2001 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
# 
##############################################################################
"""

Revision information: $Id: Form.py,v 1.1.2.1 2002/01/25 14:11:06 srichter Exp $
"""

from Zope.Publisher.Browser.AttributePublisher \
     import AttributePublisher
#from IForm import IForm
from Zope.ComponentArchitecture import getRequestView


class Form(AttributePublisher):
    """Form base class.
    """

    __implements__ = AttributePublisher.__implements__#, IForm

    name = 'Form Name'     # for use by javascript
    title = 'This is a form'
    description = ''
    method = 'post'
    enctype = ''

    _fieldViewNames = []
    template = None


    def __init__(self, context):
        """Initialize form.
        """
        self._context = context
        self._widgets = []
        

    def index(self, REQUEST, **kw):
        """ """
        return apply(self.template, (REQUEST,), kw)


    def action(self, REQUEST):
        """ """
        errors = []
        values = {}
        for widget in self.getFieldViews(REQUEST):
            value = widget.getValueFromRequest(REQUEST)
            field = widget.getContext()
            try:
                values[field.id] = field.getValidator().validate(field, value)
            except ValidationError, err:
                errors.append(err)

        if errors == []:
            for widget in self.getFieldViews(REQUEST):
                field = widget.getContext()
                field.setPropertyInContext(values[field.id])

        return self.index(REQUEST, errors=errors)


    def getFieldViews(self, REQUEST):
        """ """
        views = []
        context = self.getContext()
        for name in self._fieldViewNames:
            views.append(getRequestView(context, name, REQUEST))
        return views


    def getContext(self):
        """ """
        return self._context


=== Added File Zope3/lib/python/Zope/App/Formulator/Form.pyc ===
-í
gQ<c       sI     d  Z    d k l Z  d k l Z  d e f d „  ƒ  YZ d S(   s   

Revision information: $Id: Form.pyc,v 1.1.2.1 2002/01/25 14:11:06 srichter Exp $
(   s   AttributePublisher(   s   getRequestViews   Formc      s•    d  Z    e i Z  d Z  d Z   d Z ! d Z " d Z $ g  Z % e	 Z
 ( d „  Z / d „  Z 4 d „  Z
 H d „  Z Q d	 „  Z RS(
   s   Form base class.
    s	   Form Names   This is a forms    s   postc    s"   ( * + | |  _ , g  |  _ d S(   s   Initialize form.
        N(   s   contexts   selfs   _contexts   _widgets(   s   selfs   context(    (    s1   /opt/Zope3/lib/python/Zope/App/Formulator/Form.pys   __init__( s   c    s#   / 0 1 t  |  i | f | ƒ Sd S(   s    N(   s   applys   selfs   templates   REQUESTs   kw(   s   selfs   REQUESTs   kw(    (    s1   /opt/Zope3/lib/python/Zope/App/Formulator/Form.pys   index/ s   c    s!  4 5 6 g  } 7 h  } 8 x |  i | ƒ D8 ]{ } 9 | i | ƒ } : | i ƒ  } ; y& < | i
 ƒ  i | | ƒ | | i <Wn( = t
 j
 o } > | i | ƒ n Xq+ W@ | g  j oJ A x@ |  i | ƒ DA ], } B | i ƒ  } C | i | | i ƒ qÐ Wn E |  i | d | ƒSd S(   s    s   errorsN(   s   errorss   valuess   selfs
   getFieldViewss   REQUESTs   widgets   getValueFromRequests   values
   getContexts   fields   getValidators   validates   ids   ValidationErrors   errs   appends   setPropertyInContexts   index(   s   selfs   REQUESTs   fields   widgets   errorss   valuess   errs   value(    (    s1   /opt/Zope3/lib/python/Zope/App/Formulator/Form.pys   action4 s"   		 	& 	c    s_   H I J g  } K |  i ƒ  } L x0 |  i DL ]" } M | i t | | | ƒ ƒ q+ WN | Sd S(   s    N(	   s   viewss   selfs
   getContexts   contexts   _fieldViewNamess   names   appends   getRequestViews   REQUEST(   s   selfs   REQUESTs   contexts   names   views(    (    s1   /opt/Zope3/lib/python/Zope/App/Formulator/Form.pys
   getFieldViewsH s   	
 	 c    s   Q R S |  i Sd S(   s    N(   s   selfs   _context(   s   self(    (    s1   /opt/Zope3/lib/python/Zope/App/Formulator/Form.pys
   getContextQ s   (   s   __doc__s   AttributePublishers   __implements__s   names   titles   descriptions   methods   enctypes   _fieldViewNamess   Nones   templates   __init__s   indexs   actions
   getFieldViewss
   getContext(    (    (    s1   /opt/Zope3/lib/python/Zope/App/Formulator/Form.pys   Form s   									N(   s   __doc__s)   Zope.Publisher.Browser.AttributePublishers   AttributePublishers   Zope.ComponentArchitectures   getRequestViews   Form(   s   AttributePublishers   Forms   getRequestView(    (    s1   /opt/Zope3/lib/python/Zope/App/Formulator/Form.pys   ? s   

=== Added File Zope3/lib/python/Zope/App/Formulator/FormulatorProposal.stx ===
"""
The formulator system will serve the following purposes:

  - Providing meta data to the properties
  - Validate user input
  - Provide the infrastructure to build forms

With the various registries the 3rd party developer will be able to
develop additional extensions/components for Formulator and allows
then the system to use it. These widgets, validators and fields can
be used to create forms for the various editing screens.
"""


class IWidget(Interface):
    """A field widget contains all the properties that are required
       to represent a field. Properties include title, description,
       default value and so on.

       There seems to be no methods for this interface, since it
       will only define properties for later rendering.

       Note: Rendering will not be part of this class, since it is
             protocol-specific and the widget should be independent
             of the protocol.

    """

    def render(REQUEST):
        """
        """


    def getField():
        """
        """



class IField(Interface):
    """A field basically contains meta data for a particular
       property of a class. This way the object itself is not
       bloated.
    """

    def getValidator():
        """Get the validator of the field.
        """



class IFieldWidgetRegistry(Interface):
    """A service that registers all the available field widgets.

       Unfortunately I do not know how this interface is supposed
       to look at all, except the obvious methods.
    """

    def register(name, widget):
        """Registers a widget instance"""


    def getWidget(name):
        """Returns the widget with the specified name"""



class IForm(IBrowserPublisher):
    """The Form will be a generic description of a view that could
       be implemented for all sort of protocols.
    """

    def form(context):
        """Return the entry form in whatever form it is needed.
        """


    def action(context):
        """Execute an action having the form data.
        """


    def getObject():
        """Returns the object the action is executed upon."""



registry_examples = '''

<browser:view name="TitleWidget"
    for="Zope.App.OFS.File."
    factory="Zope.App.Formulator.Widgets.Browser.TitleWidget.">

'''


registering_of_form_view = '''

<browser:view name="form"
    for="Zope.App.OFS.File."
    factory="Zope.App.OFS.FileForm." />

'''



=== Added File Zope3/lib/python/Zope/App/Formulator/FormulatorProposal2.stx ===
Field

  Fields are objects that store meta data, such as the Dublin Core,
  for a particular property of a class. This data can be used to
  provide the user with more information than simply the name and the
  value of the property.

  I think some of the common meta data pieces (many taken from the
  Dublin Core) will include:

    - Title : Content resource name

    - Description : Content resource abstract / summary /
      table-of-contents.

    - Date : Default date (effective/created/modified) for content
      resource (ISO format)

    - CreationDate : Date content resource created (ISO format)

    - ModificationDate : Date content resource last modified (ISO
      format)

    - Type : Content resource type (e.g., Zope meta_type, or a mapping
      from it).

    
  Also, we start to notice the need for composite fields. Composite 
  fields are fields that combine a set of properties together, even
  though I do not know how the API is going to look fot that case.

  Note: I think the concept would also eliminate the complaints of the
  current implementations of the Proprties and PropertySheets, where
  the properties seem to be too "dumb". But with fields this could
  really change.


Widget (FieldView)

  Widgets are Presentation (HTML, XUL, XML-RPC, wxPython ...)
  dependent and must be implemented for each presentation
  type. Widgets are responsible to correctly present an attribute or
  property in the managed medium and also handle the returned data for
  a single property.

  Widgets will not know anything about the object they are
  representing, since the adapter will take care of this.

  Widgets will be implemented as a ViewComponent.


Validator

  Validators are responsible of insuring the data integrity of the
  property. Since we cannot trust any user-specified data, the
  validator will make sure that no invalid value will be saved in the
  object.


FormView

  A FormView is a collection of widgets and a template, for HTML a ZPT
  template, that will allow the form display itself and handle some of
  the execution/validation.

  FormViews will be implemented as a ViewComponent.


FieldRegistry

  The field registry simply registers the availability of a certain
  field. This registry will be important, since through it third
  parties can provide their own custom fields.

  Furthermore I think it would be also good to specify the type of the
  property this field is going to describe. This will have the
  advantage that we can grep a generic field for a certain type, in 
  case no field was specified for a specific property.


WidgetRegistry

  Another simple registry that will allow other developers to add more
  widgets to the system. I think it will be also very handy for the
  net, since external GUIs might provide us with new sets of widgets.
  Wee, that would be cool.


ValidatorRegistry

  Since there seems to be a need for generic validators everywhere, we
  think that it will be good to have also a registry for the 
  validators.


FieldPropertyMapper

  This registry is actually very cool, since it tells the field with
  what object and property it should interact and it should do that. I
  imagine that the FieldPropertyMapper will have the following
  properties:

    - field -- The field *instance* to be mapped.
  
    - property -- The id of the property that is going to be edited.

    - forClass -- The class (not instance), in which the property can
      be found.

    - setMethod -- This will be a link to the method that can 
      manipulate the property in the object.

    - getMethod -- This will be a link to the method that can retrieve 
      the *presentable* value of the property in the object.


  Some common operations I envision to be exected are: 

    - getFieldFor(klass, propertyName) -- Returns the field that
      handles a particular property of the class

    - getClassAndPropertyFor(field) -- Since this is a unique field 
      instance, we can also retrieve the class and property from the
      field alone.

    - getSetMethodFor(klass, propertyName) -- Returns the method that 
      can manipulate the property.

    - getGetMethodFor(klass, propertyName) -- Returns the method that 
      can get the property's value


FieldWidgetMapper

  This registry maps unique field instances with unique unique widget
  instances. This will be really helpful, since we can also make the
  difference between the various widgets, since they are all
  implementing presentation-sensitive interfaces.
  The properties would be:

    - widget -- A unique instance of any Widget.

    - field -- An instance of any Field. Note that while the widget
      might be different, representing various presentation types, 
      the field is therefore not unique.


  Some common operations might be:

    - getWidgetsFor(field) -- Returns a list of widget instances that
      are declared for the field.

    - getWidgetFor(field, PresentationType) -- Returns a single or no
      widget that represents a field for the specified presentation
      type.

    - getFieldFor(widget) -- Since the widget is a little dumb, it is 
      allways good that we are able to get its respective field.


=== Added File Zope3/lib/python/Zope/App/Formulator/__init__.py ===
##############################################################################
#
# Copyright (c) 2001 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
# 
##############################################################################
"""

Revision information: $Id: __init__.py,v 1.1.2.1 2002/01/25 14:11:06 srichter Exp $
"""


=== Added File Zope3/lib/python/Zope/App/Formulator/__init__.pyc ===
-í
ÆfQ<c       s     d  Z   d S(   s   

Revision information: $Id: __init__.pyc,v 1.1.2.1 2002/01/25 14:11:06 srichter Exp $
N(   s   __doc__(    (    (    s5   /opt/Zope3/lib/python/Zope/App/Formulator/__init__.pys   ? s