[Zope-Checkins] SVN: Products.Five/branches/1.2/ Port form fixes to
1.2
Alec Mitchell
apm13 at columbia.edu
Tue May 2 15:48:18 EDT 2006
Log message for revision 67856:
Port form fixes to 1.2
Changed:
U Products.Five/branches/1.2/CHANGES.txt
U Products.Five/branches/1.2/browser/pagetemplatefile.py
U Products.Five/branches/1.2/form/__init__.py
U Products.Five/branches/1.2/form/tests/configure.zcml
U Products.Five/branches/1.2/form/tests/forms.txt
U Products.Five/branches/1.2/form/tests/schemacontent.py
-=-
Modified: Products.Five/branches/1.2/CHANGES.txt
===================================================================
--- Products.Five/branches/1.2/CHANGES.txt 2006-05-02 19:46:35 UTC (rev 67855)
+++ Products.Five/branches/1.2/CHANGES.txt 2006-05-02 19:48:17 UTC (rev 67856)
@@ -14,6 +14,14 @@
* Fixed a problem with the new traversal look-up order and the root
object (OFS.Application.Application).
+Five 1.2.4 (unreleased)
+=======================
+
+Bugfixes
+--------
+
+* Made sure that events are fired as expected in add and edit forms.
+
Five 1.2.3 (2006-03-31)
=======================
Modified: Products.Five/branches/1.2/browser/pagetemplatefile.py
===================================================================
--- Products.Five/branches/1.2/browser/pagetemplatefile.py 2006-05-02 19:46:35 UTC (rev 67855)
+++ Products.Five/branches/1.2/browser/pagetemplatefile.py 2006-05-02 19:48:17 UTC (rev 67856)
@@ -34,10 +34,10 @@
Uses Zope 2's engine, but with security disabled and with some
initialization and API from Zope 3.
"""
-
+
def __init__(self, filename, _prefix=None, content_type=None):
# XXX doesn't use content_type yet
-
+
self.ZBindings_edit(self._default_bindings)
path = self.get_path_from_prefix(_prefix)
@@ -47,7 +47,7 @@
basepath, ext = os.path.splitext(self.filename)
self.__name__ = os.path.basename(basepath)
-
+
def get_path_from_prefix(self, _prefix):
if isinstance(_prefix, str):
path = _prefix
@@ -55,24 +55,24 @@
if _prefix is None:
_prefix = sys._getframe(2).f_globals
path = package_home(_prefix)
- return path
+ return path
_cook = rebindFunction(PageTemplateFile._cook,
getEngine=getEngine)
-
+
pt_render = rebindFunction(PageTemplateFile.pt_render,
getEngine=getEngine)
def _pt_getContext(self):
try:
root = self.getPhysicalRoot()
- view = self._getContext()
except AttributeError:
- # self has no attribute getPhysicalRoot. This typically happens
- # when the template has no proper acquisition context.
- # That also means it has no view. /regebro
root = self.context.getPhysicalRoot()
- view = None
+ # Even if the context isn't a view (when would that be exaclty?),
+ # there shouldn't be any dange in applying a view, because it
+ # won't be used. However assuming that a lack of getPhysicalRoot
+ # implies a missing view causes problems.
+ view = self._getContext()
here = self.context.aq_inner
@@ -87,7 +87,7 @@
'request': request,
'modules': ModuleImporter,
}
- if view:
+ if view is not None:
c['view'] = view
c['views'] = ViewMapper(here, request)
Modified: Products.Five/branches/1.2/form/__init__.py
===================================================================
--- Products.Five/branches/1.2/form/__init__.py 2006-05-02 19:46:35 UTC (rev 67855)
+++ Products.Five/branches/1.2/form/__init__.py 2006-05-02 19:48:17 UTC (rev 67856)
@@ -130,8 +130,14 @@
changed = applyWidgetsChanges(self, self.schema,
target=content, names=self.fieldNames)
# We should not generate events when an adapter is used.
- # That's the adapter's job.
- if changed and self.context is self.adapted:
+ # That's the adapter's job. We need to unwrap the objects to
+ # compare them, as they are wrapped differently.
+ # Additionally, we can't use Acquisition.aq_base() because
+ # it strangely returns different objects for these two even
+ # when they are identical. In particular
+ # aq_base(self.adapted) != self.adapted.aq_base :-(
+ if changed and getattr(self.context, 'aq_base', self.context)\
+ is getattr(self.adapted, 'aq_base', self.adapted):
notify(ObjectModifiedEvent(content))
except WidgetsError, errors:
self.errors = errors
@@ -152,6 +158,7 @@
status.mapping = {'date_time': str(datetime.utcnow())}
self.update_status = status
+
return status
class AddView(EditView):
@@ -187,7 +194,9 @@
def create(self, *args, **kw):
"""Do the actual instantiation."""
# hack to please typical Zope 2 factories, which expect id and title
- args = ('tmp_id', 'Temporary title') + args
+ # Any sane schema will use a unicode title, and may fail on a
+ # non-unicode one.
+ args = ('tmp_id', u'Temporary title') + args
return self._factory(*args, **kw)
def createAndAdd(self, data):
@@ -227,7 +236,6 @@
notify(ObjectCreatedEvent(content))
content = self.add(content)
-
adapted = self.schema(content)
if self._set_after_add:
@@ -238,6 +246,9 @@
field.set(adapted, data[name])
except ValidationError:
errors.append(sys.exc_info()[1])
+ # We have modified the object, so we need to publish an
+ # object-modified event:
+ notify(ObjectModifiedEvent(content))
if errors:
raise WidgetsError(*errors)
Modified: Products.Five/branches/1.2/form/tests/configure.zcml
===================================================================
--- Products.Five/branches/1.2/form/tests/configure.zcml 2006-05-02 19:46:35 UTC (rev 67855)
+++ Products.Five/branches/1.2/form/tests/configure.zcml 2006-05-02 19:48:17 UTC (rev 67856)
@@ -65,7 +65,8 @@
schema=".schemacontent.IFieldContent"
content_factory=".schemacontent.FieldContent"
name="addwidgetoverride.html"
- permission="zope2.Public">
+ permission="zope2.Public"
+ set_before_add="title description somenumber somelist">
<widget
field="description"
@@ -81,6 +82,18 @@
permission="zope2.ViewManagementScreens"
/>
+ <subscriber
+ for=".schemacontent.IFieldContent
+ zope.app.event.interfaces.IObjectModifiedEvent"
+ factory=".schemacontent.modifiedSubscriber"
+ />
+
+ <subscriber
+ for=".schemacontent.IFieldContent
+ zope.app.event.interfaces.IObjectCreatedEvent"
+ factory=".schemacontent.createdSubscriber"
+ />
+
<i18n:registerTranslations directory="locales"/>
</configure>
Modified: Products.Five/branches/1.2/form/tests/forms.txt
===================================================================
--- Products.Five/branches/1.2/form/tests/forms.txt 2006-05-02 19:46:35 UTC (rev 67855)
+++ Products.Five/branches/1.2/form/tests/forms.txt 2006-05-02 19:48:17 UTC (rev 67856)
@@ -100,7 +100,20 @@
u'title'
>>> edittest.description #XXX shouldn't we get a u'' here???
+We can also verify that the IObjectCreatedEvent was fired, and the test
+subscriber we registered set a flag indicating such:
+ >>> edittest._created_flag
+ True
+
+Because the process of adding an object often sets attributes after the
+object is created and added, and IObjectModified event should also have been
+fired:
+
+ >>> edittest._modified_flag
+ True
+ >>> del edittest._modified_flag
+
Edit forms
----------
@@ -137,6 +150,8 @@
>>> edittest.title
u'title'
>>> edittest.description #XXX shouldn't we get a u'' here???
+ >>> getattr(edittest, '_modified_flag', False)
+ False
However, when we specify the correct fields:
@@ -170,7 +185,70 @@
>>> edittest.description
u'FooDescription'
+And that the event has been fired:
+ >>> edittest._modified_flag
+ True
+ >>> del edittest._modified_flag
+
+Widget Overrides
+----------------
+
+We have an alternate add form for IFieldContent which uses a TextArea widget
+via and override in the zcml. Let's ensure that that works:
+
+ >>> print http(r"""
+ ... GET /test_folder_1_/ftf/+/addwidgetoverride.html HTTP/1.1
+ ... """, handle_errors=False)
+ HTTP/1.1 200 OK
+ ...
+ ...<textarea
+ ...
+
+ >>> print http(r"""
+ ... POST /test_folder_1_/ftf/+/addwidgetoverride.html HTTP/1.1
+ ... Authorization: Basic manager:r00t
+ ... Content-Type: multipart/form-data; boundary=---------------------------968064918930967154199105236
+ ... Content-Length: 527
+ ...
+ ... -----------------------------968064918930967154199105236
+ ... Content-Disposition: form-data; name="field.title"
+ ...
+ ... title2
+ ... -----------------------------968064918930967154199105236
+ ... Content-Disposition: form-data; name="field.description"
+ ...
+ ... Blah
+ ... -----------------------------968064918930967154199105236
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------968064918930967154199105236
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ... edittest2
+ ... -----------------------------968064918930967154199105236--
+ ... """, handle_errors=False)
+ HTTP/1.1 302 Moved Temporarily
+ ...
+ Location: http://localhost/test_folder_1_/ftf/manage_main
+ ...
+
+We also indicated that all fields for this view should be set before adding
+the content, this means that no IObjectModified event should have been fired
+
+ >>> edittest2 = self.folder.ftf.edittest2
+ >>> edittest2.title
+ u'title2'
+ >>> edittest2.description
+ u'Blah'
+ >>> edittest2._created_flag
+ True
+
+ >>> getattr(edittest2, '_modified_flag', False)
+ False
+
+
Unicode-safety of forms
-----------------------
Modified: Products.Five/branches/1.2/form/tests/schemacontent.py
===================================================================
--- Products.Five/branches/1.2/form/tests/schemacontent.py 2006-05-02 19:46:35 UTC (rev 67855)
+++ Products.Five/branches/1.2/form/tests/schemacontent.py 2006-05-02 19:48:17 UTC (rev 67856)
@@ -106,3 +106,11 @@
"""Add the complex schema content"""
id = self._setObject(id, ComplexSchemaContent(id))
return ''
+
+def modifiedSubscriber(content, ev):
+ """A simple event handler, which sets a flag on the object"""
+ content._modified_flag = True
+
+def createdSubscriber(content,ev):
+ """A simple event handler, which sets a flag on the object"""
+ content._created_flag = True
More information about the Zope-Checkins
mailing list