[Zope3-checkins] CVS: Zope3/lib/python/Zope/App/Forms/Browser - EditView.py:1.1 __init__.py:1.2 edit.pt:1.1 meta.zcml:1.1
Jim Fulton
jim@zope.com
Mon, 11 Nov 2002 15:29:59 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/App/Forms/Browser
In directory cvs.zope.org:/tmp/cvs-serv16646
Added Files:
EditView.py __init__.py edit.pt meta.zcml
Log Message:
Added a mechanism for customizable automatic editing views. Views
are generated from a schema and can be customized with a class or an
alternate template.
=== Added File Zope3/lib/python/Zope/App/Forms/Browser/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 2002/11/11 20:29:58 jim Exp $
"""
from datetime import datetime
from Zope.Publisher.Browser.BrowserView import BrowserView
from Zope.App.Forms.Views.Browser import Widget
from Zope.App.Forms.Exceptions import WidgetsError
from Zope.App.Forms.Utility import setUpEditWidgets, 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
class EditView(BrowserView):
"""Simple edit-view base class
Subclasses should provide a schema attribute defining the schema
to be edited.
"""
errors = ()
label = ''
generated_form = index = ViewPageTemplateFile('edit.pt')
def __init__(self, context, request):
super(EditView, self).__init__(context, request)
setUpEditWidgets(self, self.schema)
def setPrefix(self, prefix):
for widget in self.widgets():
widget.setPrefix(prefix)
def __call__(self, *args, **kw):
return self.index(*args, **kw)
def widgets(self):
return [getattr(self, name)
for name in fieldNames(self.schema)
]
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)
return unchanged
def update(self):
if "save_submit" in self.request:
unchanged = True
try:
data = getWidgetsData(self, self.schema, required=0)
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)
if not unchanged:
return "Updated %s" % datetime.utcnow()
return ''
def EditViewFactory(name, schema, label, permission, layer,
template, class_, for_):
if class_ is None:
bases = EditView,
else:
bases = class_, EditView
class_ = SimpleViewClass(
template,
used_for = schema, bases = bases
)
class_.schema = schema
class_.label = label
defineChecker(class_,
NamesChecker(
("__call__", "__getitem__", "browserDefault"),
permission,
)
)
provideView(for_, name, IBrowserPresentation, class_, layer)
def directive(_context, name, schema, label,
permission = 'Zope.Public', layer = "default",
class_ = None, for_ = None,
template = None):
schema = _context.resolve(schema)
if for_ is None:
for_ = schema
else:
for_ = _context.resolve(for_)
if class_ is not None:
class_ = _context.resolve(class_)
if template is not None:
template = _context.path(template)
else:
template = 'edit.pt'
template = str(template)
return [
Action(
discriminator = ('http://namespaces.zope.org/form/edit',
name, for_, layer),
callable = EditViewFactory,
args = (name, schema, label, permission, layer, template, class_,
for_),
)
]
=== Zope3/lib/python/Zope/App/Forms/Browser/__init__.py 1.1 => 1.2 ===
--- /dev/null Mon Nov 11 15:29:58 2002
+++ Zope3/lib/python/Zope/App/Forms/Browser/__init__.py Mon Nov 11 15:29:58 2002
@@ -0,0 +1,13 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
=== Added File Zope3/lib/python/Zope/App/Forms/Browser/edit.pt ===
<html metal:use-macro="views/standard_macros/page">
<body>
<div metal:fill-slot="body">
<div metal:define-macro="body">
<h1 tal:condition="view/label"
tal:content="view/label">Edit something</h1>
<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>
<form action="." tal:attributes="action request/URL" method="POST"
enctype="multipart/form-data"
>
<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>
<input type="submit" value="Refresh" />
<input type="submit" name="save_submit" value="Save Changes" />
</form>
</div>
</div>
</body>
</html>
=== Added File Zope3/lib/python/Zope/App/Forms/Browser/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=".EditView.directive"
/>
</directives>
</zopeConfigure>