[Zope3-checkins] CVS: Zope3/src/zope/app/browser/form - __init__.py:1.1.2.1 add.py:1.1.2.1 configure.zcml:1.1.2.1 edit.pt:1.1.2.1 editview.py:1.1.2.1 meta.zcml:1.1.2.1 subedit.pt:1.1.2.1 submit.py:1.1.2.1 widget.py:1.1.2.1
Jim Fulton
jim@zope.com
Mon, 23 Dec 2002 14:31:09 -0500
Update of /cvs-repository/Zope3/src/zope/app/browser/form
In directory cvs.zope.org:/tmp/cvs-serv19908/zope/app/browser/form
Added Files:
Tag: NameGeddon-branch
__init__.py add.py configure.zcml edit.pt editview.py
meta.zcml subedit.pt submit.py widget.py
Log Message:
Initial renaming before debugging
=== Added File Zope3/src/zope/app/browser/form/__init__.py ===
#
# This file is necessary to make this directory a package.
=== Added File Zope3/src/zope/app/browser/form/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/23 19:31:07 jim Exp $
"""
import sys
from zope.event import publish
from zope.app.event.objectevent import ObjectCreatedEvent
from zope.app.interfaces.forms import WidgetsError
from zope.app.form.utility import setUpWidgets, getWidgetsData
from zope.app.form.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.component.view import provideView
from zope.publisher.interfaces.browser import IBrowserPresentation
from zope.app.pagetemplate.simpleviewclass import SimpleViewClass
from zope.app.browser.form.submit import Update
from zope.app.browser.form.editview import EditView, _normalize
from zope.app.interfaces.container 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:
if name in data:
kw[str(name)] = data[name]
content = self._factory(*args, **kw)
errors = []
for name in self._set_before_add:
if name in data:
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:
if name in data:
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, 'edit.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
else:
set_after_add = leftover
return [
Action(
discriminator = ('http://namespaces.zope.org/form/add', name, layer),
callable = AddViewFactory,
args = (name, schema, label, permission, layer, template, 'edit.pt',
bases,
IAdding, fields, content_factory, arguments,
keyword_arguments, set_before_add, set_after_add),
)
]
=== Added File Zope3/src/zope/app/browser/form/configure.zcml ===
<zopeConfigure
xmlns='http://namespaces.zope.org/zope'
xmlns:browser='http://namespaces.zope.org/browser'
package="Zope.App.Forms.Views.Browser"
>
<!-- Form Widget View Directives -->
<browser:defaultView for="zope.schema.interfaces.IField" name="edit" />
<browser:view
permission="Zope.Public"
allowed_interface="zope.app.interfaces.browser.form.IBrowserWidget"
for="zope.schema.interfaces.ITextLine"
name="edit"
factory="zope.app.browser.form.widget.TextWidget" />
<browser:view
permission="Zope.Public"
allowed_interface="zope.app.interfaces.browser.form.IBrowserWidget"
for="zope.schema.interfaces.IText"
name="edit"
factory="zope.app.browser.form.widget.TextAreaWidget" />
<browser:view
permission="Zope.Public"
allowed_interface="zope.app.interfaces.browser.form.IBrowserWidget"
for="zope.schema.interfaces.IBytesLine"
name="edit"
factory="zope.app.browser.form.widget.BytesWidget" />
<browser:view
permission="Zope.Public"
allowed_interface="zope.app.interfaces.browser.form.IBrowserWidget"
for="zope.schema.interfaces.IBytes"
name="edit"
factory="zope.app.browser.form.widget.BytesAreaWidget" />
<browser:view
permission="Zope.Public"
allowed_interface="zope.app.interfaces.browser.form.IBrowserWidget"
for="zope.schema.interfaces.IInt"
name="edit"
factory="zope.app.browser.form.widget.IntWidget" />
<browser:view
permission="Zope.Public"
allowed_interface="zope.app.interfaces.browser.form.IBrowserWidget"
for="zope.schema.interfaces.IFloat"
name="edit"
factory="zope.app.browser.form.widget.FloatWidget" />
<browser:view
permission="Zope.Public"
allowed_interface="zope.app.interfaces.browser.form.IBrowserWidget"
for="zope.schema.interfaces.IBool"
name="edit"
factory="zope.app.browser.form.widget.CheckBoxWidget" />
<browser:view
permission="Zope.Public"
allowed_interface="zope.app.interfaces.browser.form.IBrowserWidget"
for="zope.schema.interfaces.ITuple"
name="edit"
factory="zope.app.browser.form.widget.TextAreaWidget" />
<browser:view
permission="Zope.Public"
allowed_interface="zope.app.interfaces.browser.form.IBrowserWidget"
for="zope.schema.interfaces.IList"
name="edit"
factory="zope.app.browser.form.widget.TextAreaWidget" />
<!-- Default simple display view -->
<browser:view
permission="Zope.Public"
allowed_interface="zope.app.interfaces.browser.form.IBrowserWidget"
for="zope.schema.interfaces.IField"
name="display"
factory="zope.app.browser.form.widget.DisplayWidget" />
</zopeConfigure>
=== Added File Zope3/src/zope/app/browser/form/edit.pt ===
<html metal:use-macro="views/standard_macros/dialog">
<body>
<div metal:fill-slot="body">
<div metal:define-macro="body">
<form action="." tal:attributes="action request/URL" method="POST"
enctype="multipart/form-data"
>
<div metal:define-macro="formbody">
<h3 tal:condition="view/label"
tal:content="view/label"
metal:define-slot="heading"
>Edit something</h3>
<p tal:define="status view/update"
tal:condition="status"
tal:content="status" />
<div tal:condition="view/errors">
<ul>
<li tal:repeat="error view/errors">
<strong tal:content="error/__class__">
Error Type</strong>:
<span tal:content="error">Error text</span>
</li>
</ul>
</div>
<div metal:define-slot="extra_info" tal:replace="nothing">
</div>
<table width="100%" border="0">
<tr metal:define-slot="extra_top" tal:replace="nothing">
<td>Extra top</td>
<td><input type="text" style="width:100%" /></td>
</tr>
<tr metal:define-macro="widget_rows" tal:repeat="widget view/widgets"
tal:content="structure widget/row">
<td>Name</td>
<td><input type="text" style="width:100%" /></td>
</tr>
<tr metal:define-slot="extra_bottom" tal:replace="nothing">
<td>Extra bottom</td>
<td><input type="text" style="width:100%" /></td>
</tr>
</table>
</div>
<input type="submit" value="Refresh" />
<input type="submit" name="UPDATE_SUBMIT" value="Save Changes" />
</form>
</div>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/browser/form/editview.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: editview.py,v 1.1.2.1 2002/12/23 19:31:07 jim Exp $
"""
from datetime import datetime
from zope.event import publish
from zope.app.event.objectevent import ObjectModifiedEvent
from zope.publisher.browser import BrowserView
from Zope.App.Forms.Views.Browser import Widget
from zope.app.interfaces.forms import WidgetsError
from zope.app.form.utility import setUpEditWidgets, getWidgetsData
from zope.app.form.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.component.view import provideView
from zope.publisher.interfaces.browser import IBrowserPresentation
from zope.app.pagetemplate.simpleviewclass import SimpleViewClass
from zope.app.browser.form.submit import Update
class EditView(BrowserView):
"""Simple edit-view base class
Subclasses should provide a schema attribute defining the schema
to be edited.
"""
errors = ()
label = ''
# Fall-back field names computes from schema
fieldNames = property(lambda self: fieldNames(self.schema))
def __init__(self, context, request):
super(EditView, self).__init__(context, request)
setUpEditWidgets(self, self.schema, names=self.fieldNames)
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 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.
"""
content = self.context
errors = []
unchanged = True
for name in data:
# OK, we really got a field
try:
newvalue = data[name]
# We want to see if the data changes. Unfortunately,
# we don't know enough to know that we won't get some
# strange error, so we'll carefully ignore errors and
# assume we should update the data if we can't be sure
# it's the same.
change = True
try:
# Use self as a marker
change = getattr(content, name, self) != newvalue
except:
pass
if change:
setattr(content, name, data[name])
unchanged = False
except Exception, v:
errors.append(v)
if errors:
raise WidgetsError(*errors)
if not unchanged:
publish(content, ObjectModifiedEvent(content))
return unchanged
def update(self):
if Update in self.request:
unchanged = True
try:
data = getWidgetsData(self, self.schema,
required=0, names=self.fieldNames)
unchanged = 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."
else:
setUpEditWidgets(self, self.schema, force=1,
names=self.fieldNames)
if not unchanged:
return "Updated %s" % datetime.utcnow()
return ''
def EditViewFactory(name, schema, label, permission, layer,
template, default_template, bases, for_, fields,
fulledit_path=None, fulledit_label=None):
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 edit"
class_.fulledit_label = fulledit_label
class_.generated_form = ViewPageTemplateFile(default_template)
defineChecker(class_,
NamesChecker(
("__call__", "__getitem__", "browserDefault"),
permission,
)
)
provideView(for_, name, IBrowserPresentation, class_, layer)
def _normalize(_context, schema_, for_, class_, template, default_template,
fields, omit, view=EditView):
schema = _context.resolve(schema_)
if for_ is None:
for_ = schema
else:
for_ = _context.resolve(for_)
if class_ is None:
bases = (view, )
else:
bases = (_context.resolve(class_), view)
if template is not None:
template = _context.path(template)
else:
template = default_template
template = str(template)
names = fieldNames(schema)
if fields:
fields = fields.split()
for name in fields:
if name not in names:
raise ValueError("Field name %s is not in schema %s",
name, schema_)
else:
fields = names
if omit:
omit = omit.split()
for name in omit:
if name not in names:
raise ValueError("Field name %s is not in schema %s",
name, schema_)
fields = [name for name in fields if name not in omit]
return schema, for_, bases, template, fields
def edit(_context, name, schema, label,
permission = 'Zope.Public', layer = "default",
class_ = None, for_ = None,
template = None, omit=None, fields=None):
(schema, for_, bases, template, fields,
) = _normalize(
_context, schema, for_, class_, template, 'edit.pt', fields, omit)
return [
Action(
discriminator = ('http://namespaces.zope.org/form/edit',
name, for_, layer),
callable = EditViewFactory,
args = (name, schema, label, permission, layer, template, 'edit.pt',
bases,
for_, fields),
)
]
def subedit(_context, name, schema, label,
permission = 'Zope.Public', layer = "default",
class_ = None, for_ = None,
template = None, omit=None, fields=None,
fulledit=None, fulledit_label=None):
(schema, for_, bases, template, fields,
) = _normalize(
_context, schema, for_, class_, template, 'subedit.pt', fields, omit)
return [
Action(
discriminator = ('http://namespaces.zope.org/form/subedit',
name, for_, layer),
callable = EditViewFactory,
args = (name, schema, label, permission, layer, template, 'subedit.pt',
bases,
for_, fields, fulledit, fulledit_label),
)
]
=== Added File Zope3/src/zope/app/browser/form/meta.zcml ===
<zopeConfigure xmlns='http://namespaces.zope.org/zope'>
<directives namespace="http://namespaces.zope.org/form">
<directive
name="edit"
attributes="name schema label for layer permission class template"
handler="zope.app.browser.form.editview.edit"
/>
<directive
name="subedit"
attributes="name schema label for layer permission class template
fulledit fulledit_label"
handler="zope.app.browser.form.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="zope.app.browser.form.add.add"
/>
</directives>
</zopeConfigure>
=== Added File Zope3/src/zope/app/browser/form/subedit.pt ===
<div metal:define-macro="formbody">
<span tal:condition="view/label"
tal:content="view/label"
metal:define-slot="heading"
>
Edit something
</span>
<p tal:condition="view/fulledit_label">
<a tal:attributes="href
string:${context/@@absolute_url}/${view/fulledit_path}"
tal:content="view/fulledit_label">Full edit</a>
</p>
<p tal:define="status view/update"
tal:condition="status"
tal:content="status" />
<div tal:condition="view/errors">
<ul>
<li tal:repeat="error view/errors">
<strong tal:content="error/__class__">
Error Type</strong>:
<span tal:content="error">Error text</span>
</li>
</ul>
</div>
<div metal:define-slot="extra_info" tal:replace="nothing">
</div>
<table width="100%" border="0">
<tr metal:define-slot="extra_top" tal:replace="nothing">
<td>Extra top</td>
<td><input type="text" style="width:100%" /></td>
</tr>
<tr metal:define-macro="widget_rows" tal:repeat="widget view/widgets"
tal:content="structure widget/row">
<td>Name</td>
<td><input type="text" style="width:100%" /></td>
</tr>
<tr metal:define-slot="extra_bottom" tal:replace="nothing">
<td>Extra bottom</td>
<td><input type="text" style="width:100%" /></td>
</tr>
</table>
</div>
=== Added File Zope3/src/zope/app/browser/form/submit.py ===
##############################################################################
#
# Copyright (c) 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.
#
##############################################################################
"""Standard submit button names
Update -- Name of the standard update submit button
$Id: submit.py,v 1.1.2.1 2002/12/23 19:31:07 jim Exp $
"""
Update = "UPDATE_SUBMIT"
=== Added File Zope3/src/zope/app/browser/form/widget.py === (530/630 lines abridged)
##############################################################################
#
# 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: widget.py,v 1.1.2.1 2002/12/23 19:31:07 jim Exp $
"""
__metaclass__ = type
import sys
from types import ListType, TupleType
ListTypes = (ListType, TupleType)
from zope.component import getAdapter
from zope.proxy.introspection import removeAllProxies
from zope.publisher.browser import BrowserView
from zope.app.interfaces.browser.form import IBrowserWidget
from zope.app.form.widget import Widget
from zope.app.interfaces.forms import ConversionError, WidgetInputError, MissingInputError
from zope.schema.interfaces import ValidationError
class BrowserWidget(Widget, BrowserView):
"""A field widget that knows how to display itself as HTML."""
__implements__ = IBrowserWidget
propertyNames = (Widget.propertyNames +
['tag', 'type', 'cssClass', 'extra'])
tag = 'input'
type = 'text'
cssClass = ''
extra = ''
_missing = None
def haveData(self):
if (self.name) in self.request.form:
return self._convert(self.request[self.name]) is not None
return False
[-=- -=- -=- 530 lines omitted -=- -=- -=-]
type = "checkbox",
cssClass = cssClass,
name = name,
value = value) + text
def renderSelectedItem(self, text, value, name, cssClass):
return renderElement('input',
type = "checkbox",
cssClass = cssClass,
name = name,
value = value,
checked = None) + text
# XXX Note, some HTML quoting is needed in renderTag and renderElement.
def renderTag(tag, **kw):
"""Render the tag. Well, not all of it, as we may want to / it."""
attr_list = []
# special case handling for cssClass
if 'cssClass' in kw:
if kw['cssClass'] != "":
attr_list.append('class="%s"' % kw['cssClass'])
del kw['cssClass']
# special case handling for extra 'raw' code
if 'extra' in kw:
extra = kw['extra'] # could be empty string but we don't care
del kw['extra']
else:
extra = ""
# handle other attributes
for key, value in kw.items():
if value == None:
value = key
attr_list.append('%s="%s"' % (key, str(value)))
attr_str = " ".join(attr_list)
return "<%s %s %s" % (tag, attr_str, extra)
def renderElement(tag, **kw):
if 'contents' in kw:
contents = kw['contents']
del kw['contents']
return "%s>%s</%s>" % (apply(renderTag, (tag,), kw), contents, tag)
else:
return apply(renderTag, (tag,), kw) + " />"