[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