[Zope3-checkins] CVS: Zope3/lib/python/Zope/App/Forms/Browser - add.py:1.1.2.1 EditView.py:1.4.2.1 meta.zcml:1.2.2.1
Jim Fulton
jim@zope.com
Thu, 12 Dec 2002 13:33:55 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/App/Forms/Browser
In directory cvs.zope.org:/tmp/cvs-serv17714/lib/python/Zope/App/Forms/Browser
Modified Files:
Tag: AdapterAndView-branch
EditView.py meta.zcml
Added Files:
Tag: AdapterAndView-branch
add.py
Log Message:
Added a generic schema-driven add view.
We have unit tests, but we still need to test it in practice.
=== Added File Zope3/lib/python/Zope/App/Forms/Browser/add.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.
#
##############################################################################
"""
$Id: add.py,v 1.1.2.1 2002/12/12 18:33:54 jim Exp $
"""
from Zope.Event import publish
from Zope.Event.ObjectEvent import ObjectCreatedEvent
from Zope.App.Forms.Exceptions import WidgetsError
from Zope.App.Forms.Utility import setUpWidgets, getWidgetsData
from Zope.App.Forms.Utility import haveWidgetsData, fieldNames
from Zope.Configuration.Action import Action
from Zope.App.PageTemplate.ViewPageTemplateFile import ViewPageTemplateFile
from Zope.Security.Checker import defineChecker, NamesChecker
from Zope.ComponentArchitecture.GlobalViewService import provideView
from Zope.Publisher.Browser.IBrowserPresentation import IBrowserPresentation
from Zope.App.PageTemplate.SimpleViewClass import SimpleViewClass
from Zope.App.Forms.Browser.StandardSubmit import Update
from EditView import EditView, _normalize
from Zope.App.OFS.Container.IAdding import IAdding
class AddView(EditView):
"""Simple edit-view base class
Subclasses should provide a schema attribute defining the schema
to be edited.
"""
def __init__(self, context, request):
super(EditView, self).__init__(context, request)
setUpWidgets(self, self.schema, names=self.fieldNames)
def apply_update(self, data):
"""Apply data updates
Return true if data were unchanged and false otherwise.
This sounds backwards, but it allows lazy implementations to
avoid tracking changes.
"""
args = []
for name in self._arguments:
args.append(data[name])
kw = {}
for name in self._keyword_arguments:
kw[name] = data[name]
content = self._factory(*args, **kw)
errors = []
for name in self._set_before_add:
try:
setattr(content, name, data[name])
except:
# Yes, I want a bare except here to catch all errors and
# include them in the error list
errors.append(sys.exc_info()[1])
if errors:
raise WidgetsError(*errors)
publish(content, ObjectCreatedEvent(content))
try:
content = self.context.add(content)
except:
errors.append(sys.exc_info()[1])
raise WidgetsError(*errors)
for name in self._set_after_add:
try:
setattr(content, name, data[name])
except:
# Yes, I want a bare except here to catch all errors and
# include them in the error list
errors.append(sys.exc_info()[1])
if errors:
raise WidgetsError(*errors)
return content
def update(self):
if Update in self.request:
try:
data = getWidgetsData(self, self.schema,
required=0, names=self.fieldNames)
content = self.apply_update(data)
except WidgetsError, errors:
self.errors = errors
return u"An error occured."
except Exception, v:
self.errors = (v, )
return u"An error occured."
self.request.response.redirect(self.context.nextURL())
def AddViewFactory(name, schema, label, permission, layer,
template, default_template, bases, for_,
fields, content_factory, arguments,
keyword_arguments, set_before_add, set_after_add):
class_ = SimpleViewClass(
template,
used_for = schema, bases = bases
)
class_.schema = schema
class_.label = label
class_.fieldNames = fields
class_._factory = content_factory
class_._arguments = arguments
class_._keyword_arguments = keyword_arguments
class_._set_before_add = set_before_add
class_._set_after_add = set_after_add
class_.generated_form = ViewPageTemplateFile(default_template)
defineChecker(class_,
NamesChecker(
("__call__", "__getitem__", "browserDefault"),
permission,
)
)
provideView(for_, name, IBrowserPresentation, class_, layer)
def add(_context, name, schema, label, content_factory,
permission = 'Zope.Public', layer = "default",
class_ = None, for_ = None,
template = None, omit=None, fields=None,
arguments='', keyword_arguments='',
set_before_add='', set_after_add=''):
content_factory = _context.resolve(content_factory)
(schema, for_, bases, template, fields,
) = _normalize(
_context, schema, for_, class_, template, 'add.pt', fields, omit,
AddView)
leftover = fields
if arguments:
arguments = arguments.split()
missing = [n for n in arguments if n not in fields]
if missing:
raise ValueError("Some arguments are not included in the form",
missing)
leftover = [n for n in leftover if n not in arguments]
if keyword_arguments:
keyword_arguments = keyword_arguments.split()
missing = [n for n in keyword_arguments if n not in fields]
if missing:
raise ValueError(
"Some keyword_arguments are not included in the form",
missing)
leftover = [n for n in leftover if n not in keyword_arguments]
if set_before_add:
set_before_add = set_before_add.split()
missing = [n for n in set_before_add if n not in fields]
if missing:
raise ValueError(
"Some set_before_add are not included in the form",
missing)
leftover = [n for n in leftover if n not in set_before_add]
if set_after_add:
set_after_add = set_after_add.split()
missing = [n for n in set_after_add if n not in fields]
if missing:
raise ValueError(
"Some set_after_add are not included in the form",
missing)
leftover = [n for n in leftover if n not in set_after_add]
set_after_add += leftover
return [
Action(
discriminator = ('http://namespaces.zope.org/form/add', name, layer),
callable = AddViewFactory,
args = (name, schema, label, permission, layer, template, 'add.pt',
bases,
IAdding, fields, content_factory, arguments,
keyword_arguments, set_before_add, set_after_add),
)
]
=== Zope3/lib/python/Zope/App/Forms/Browser/EditView.py 1.4 => 1.4.2.1 ===
--- Zope3/lib/python/Zope/App/Forms/Browser/EditView.py:1.4 Wed Dec 11 08:55:59 2002
+++ Zope3/lib/python/Zope/App/Forms/Browser/EditView.py Thu Dec 12 13:33:54 2002
@@ -151,7 +151,7 @@
def _normalize(_context, schema_, for_, class_, template, default_template,
- fields, omit):
+ fields, omit, view=EditView):
schema = _context.resolve(schema_)
if for_ is None:
@@ -160,9 +160,9 @@
for_ = _context.resolve(for_)
if class_ is None:
- bases = (EditView, )
+ bases = (view, )
else:
- bases = (_context.resolve(class_), EditView)
+ bases = (_context.resolve(class_), view)
if template is not None:
=== Zope3/lib/python/Zope/App/Forms/Browser/meta.zcml 1.2 => 1.2.2.1 ===
--- Zope3/lib/python/Zope/App/Forms/Browser/meta.zcml:1.2 Wed Dec 11 08:55:59 2002
+++ Zope3/lib/python/Zope/App/Forms/Browser/meta.zcml Thu Dec 12 13:33:54 2002
@@ -14,6 +14,14 @@
handler=".EditView.subedit"
/>
+ <directive
+ name="add"
+ attributes="name schema label for layer permission class
+ template content_factory argument keyword_arguments
+ set_before_add set_after_add"
+ handler=".add."
+ />
+
</directives>
</zopeConfigure>