[Zope-Checkins] SVN: Zope/trunk/lib/python/ Updated to use Five
1.3b2, and merged efge-five-events-work:
Florent Guillaume
fg at nuxeo.com
Thu Nov 10 10:05:07 EST 2005
Log message for revision 40026:
Updated to use Five 1.3b2, and merged efge-five-events-work:
Fixed bug that broke WebDAV access for five:defaultViewable objects. The
__browser_default__ now modifies only GET and POST requests.
Fixed some event recursion compatibility modes.
Changed:
U Zope/trunk/lib/python/OFS/CopySupport.py
U Zope/trunk/lib/python/OFS/ObjectManager.py
U Zope/trunk/lib/python/OFS/SimpleItem.py
U Zope/trunk/lib/python/OFS/subscribers.py
U Zope/trunk/lib/python/Products/BTreeFolder2/BTreeFolder2.py
U Zope/trunk/lib/python/Products/Five/CHANGES.txt
A Zope/trunk/lib/python/Products/Five/COPYING.txt
A Zope/trunk/lib/python/Products/Five/INSTALL.txt
A Zope/trunk/lib/python/Products/Five/doc/ZopePublicLicense.txt
A Zope/trunk/lib/python/Products/Five/doc/event.txt
A Zope/trunk/lib/python/Products/Five/doc/i18n.txt
A Zope/trunk/lib/python/Products/Five/doc/presentations/
A Zope/trunk/lib/python/Products/Five/doc/presentations/five.mgp
A Zope/trunk/lib/python/Products/Five/doc/presentations/five_directions.mgp
A Zope/trunk/lib/python/Products/Five/doc/presentations/five_interface_tutorial.mgp
A Zope/trunk/lib/python/Products/Five/doc/presentations/five_intro.mgp
A Zope/trunk/lib/python/Products/Five/doc/presentations/five_misc_tutorial.mgp
A Zope/trunk/lib/python/Products/Five/doc/presentations/five_views_tutorial.mgp
A Zope/trunk/lib/python/Products/Five/doc/presentations/z3-banner.png
D Zope/trunk/lib/python/Products/Five/doc/products/ViewsTutorial/www/demoContentAdd.zpt
D Zope/trunk/lib/python/Products/Five/makefile.in
U Zope/trunk/lib/python/Products/Five/tests/event.txt
U Zope/trunk/lib/python/Products/Five/tests/test_event.py
U Zope/trunk/lib/python/Products/Five/tests/test_viewable.py
A Zope/trunk/lib/python/Products/Five/tests/viewable.txt
U Zope/trunk/lib/python/Products/Five/version.txt
U Zope/trunk/lib/python/Products/Five/viewable.py
-=-
Modified: Zope/trunk/lib/python/OFS/CopySupport.py
===================================================================
--- Zope/trunk/lib/python/OFS/CopySupport.py 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/OFS/CopySupport.py 2005-11-10 15:05:07 UTC (rev 40026)
@@ -222,7 +222,7 @@
ob._postCopy(self, op=0)
- OFS.subscribers.maybeCallDeprecated('manage_afterClone', ob)
+ OFS.subscribers.compatibilityCall('manage_afterClone', ob, ob)
notify(ObjectClonedEvent(ob))
@@ -388,7 +388,7 @@
ob._postCopy(self, op=0)
- OFS.subscribers.maybeCallDeprecated('manage_afterClone', ob)
+ OFS.subscribers.compatibilityCall('manage_afterClone', ob, ob)
notify(ObjectClonedEvent(ob))
Modified: Zope/trunk/lib/python/OFS/ObjectManager.py
===================================================================
--- Zope/trunk/lib/python/OFS/ObjectManager.py 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/OFS/ObjectManager.py 2005-11-10 15:05:07 UTC (rev 40026)
@@ -50,7 +50,6 @@
from OFS.event import ObjectWillBeRemovedEvent
import OFS.subscribers
-
# the name BadRequestException is relied upon by 3rd-party code
BadRequestException = BadRequest
@@ -315,35 +314,23 @@
if not suppress_events:
notify(ObjectAddedEvent(ob, self, id))
- OFS.subscribers.maybeCallDeprecated('manage_afterAdd', ob, self)
+ OFS.subscribers.compatibilityCall('manage_afterAdd', ob, ob, self)
return id
def manage_afterAdd(self, item, container):
# Don't do recursion anymore, a subscriber does that.
- warnings.warn(
- "%s.manage_afterAdd is deprecated and will be removed in "
- "Zope 2.11, you should use an IObjectAddedEvent "
- "subscriber instead." % self.__class__.__name__,
- DeprecationWarning, stacklevel=2)
+ pass
manage_afterAdd.__five_method__ = True
def manage_afterClone(self, item):
# Don't do recursion anymore, a subscriber does that.
- warnings.warn(
- "%s.manage_afterClone is deprecated and will be removed in "
- "Zope 2.11, you should use an IObjectClonedEvent "
- "subscriber instead." % self.__class__.__name__,
- DeprecationWarning, stacklevel=2)
+ pass
manage_afterClone.__five_method__ = True
def manage_beforeDelete(self, item, container):
# Don't do recursion anymore, a subscriber does that.
- warnings.warn(
- "%s.manage_beforeDelete is deprecated and will be removed in "
- "Zope 2.11, you should use an IObjectWillBeRemovedEvent "
- "subscriber instead." % self.__class__.__name__,
- DeprecationWarning, stacklevel=2)
+ pass
manage_beforeDelete.__five_method__ = True
def _delObject(self, id, dp=1, suppress_events=False):
@@ -353,7 +340,7 @@
"""
ob = self._getOb(id)
- OFS.subscribers.maybeCallDeprecated('manage_beforeDelete', ob, self)
+ OFS.subscribers.compatibilityCall('manage_beforeDelete', ob, ob, self)
if not suppress_events:
notify(ObjectWillBeRemovedEvent(ob, self, id))
Modified: Zope/trunk/lib/python/OFS/SimpleItem.py
===================================================================
--- Zope/trunk/lib/python/OFS/SimpleItem.py 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/OFS/SimpleItem.py 2005-11-10 15:05:07 UTC (rev 40026)
@@ -61,27 +61,15 @@
isTopLevelPrincipiaApplicationObject=0
def manage_afterAdd(self, item, container):
- warnings.warn(
- "%s.manage_afterAdd is deprecated and will be removed in "
- "Zope 2.11, you should use an IObjectAddedEvent "
- "subscriber instead." % self.__class__.__name__,
- DeprecationWarning, stacklevel=2)
+ pass
manage_afterAdd.__five_method__ = True
def manage_beforeDelete(self, item, container):
- warnings.warn(
- "%s.manage_beforeDelete is deprecated and will be removed in "
- "Zope 2.11, you should use an IObjectWillBeRemovedEvent "
- "subscriber instead." % self.__class__.__name__,
- DeprecationWarning, stacklevel=2)
+ pass
manage_beforeDelete.__five_method__ = True
def manage_afterClone(self, item):
- warnings.warn(
- "%s.manage_afterClone is deprecated and will be removed in "
- "Zope 2.11, you should use an IObjectClonedEvent "
- "subscriber instead." % self.__class__.__name__,
- DeprecationWarning, stacklevel=2)
+ pass
manage_afterClone.__five_method__ = True
# Direct use of the 'id' attribute is deprecated - use getId()
Modified: Zope/trunk/lib/python/OFS/subscribers.py
===================================================================
--- Zope/trunk/lib/python/OFS/subscribers.py 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/OFS/subscribers.py 2005-11-10 15:05:07 UTC (rev 40026)
@@ -21,6 +21,7 @@
import sys
from zLOG import LOG, ERROR
+from Acquisition import aq_base
from App.config import getConfiguration
from AccessControl import getSecurityManager
from ZODB.POSException import ConflictError
@@ -35,36 +36,42 @@
deprecatedManageAddDeleteClasses = []
-def hasDeprecatedMethods(ob):
- """Do we need to call the deprecated methods?
+def compatibilityCall(method_name, *args):
+ """Call a method if events have not been setup yet.
+
+ This is the case for some unit tests that have not been converted to
+ use the component architecture.
"""
- for class_ in deprecatedManageAddDeleteClasses:
- if isinstance(ob, class_):
- return True
- return False
+ if deprecatedManageAddDeleteClasses:
+ # Events initialized, don't do compatibility call
+ return
+ if method_name == 'manage_afterAdd':
+ callManageAfterAdd(*args)
+ elif method_name == 'manage_beforeDelete':
+ callManageBeforeDelete(*args)
+ else:
+ callManageAfterClone(*args)
-def maybeCallDeprecated(method_name, ob, *args):
- """Call a deprecated method, if the framework doesn't call it already.
+def maybeWarnDeprecated(ob, method_name):
+ """Send a warning if a method is deprecated.
"""
- if hasDeprecatedMethods(ob):
- # Already deprecated through zcml
+ if not deprecatedManageAddDeleteClasses:
+ # Directives not fully loaded
return
- method = getattr(ob, method_name)
- if getattr(method, '__five_method__', False):
+ for cls in deprecatedManageAddDeleteClasses:
+ if isinstance(ob, cls):
+ # Already deprecated through zcml
+ return
+ if getattr(getattr(ob, method_name), '__five_method__', False):
# Method knows it's deprecated
return
- if deprecatedManageAddDeleteClasses:
- # Not deprecated through zcml and directives fully loaded
- class_ = ob.__class__
- warnings.warn(
- "Calling %s.%s.%s is deprecated when using Five, "
- "instead use event subscribers or "
- "mark the class with <five:deprecatedManageAddDelete/>"
- % (class_.__module__, class_.__name__, method_name),
- DeprecationWarning)
- # Note that calling the method can lead to incorrect behavior
- # but in the most common case that's better than not calling it.
- method(ob, *args)
+ class_ = ob.__class__
+ warnings.warn(
+ "%s.%s.%s is deprecated and will be removed in Zope 2.11, "
+ "you should use event subscribers instead, and meanwhile "
+ "mark the class with <five:deprecatedManageAddDelete/>"
+ % (class_.__module__, class_.__name__, method_name),
+ DeprecationWarning)
##################################################
@@ -98,16 +105,13 @@
if OFS.interfaces.IObjectManager.providedBy(ob):
dispatchToSublocations(ob, event)
# Next, do the manage_beforeDelete dance
- #import pdb; pdb.set_trace()
- if hasDeprecatedMethods(ob):
- callManageBeforeDelete(ob, event)
+ callManageBeforeDelete(ob, event.object, event.oldParent)
def dispatchObjectMovedEvent(ob, event):
"""Multi-subscriber for IItem + IObjectMovedEvent.
"""
# First, do the manage_afterAdd dance
- if hasDeprecatedMethods(ob):
- callManageAfterAdd(ob, event)
+ callManageAfterAdd(ob, event.object, event.newParent)
# Next, dispatch to sublocations
if OFS.interfaces.IObjectManager.providedBy(ob):
dispatchToSublocations(ob, event)
@@ -116,32 +120,33 @@
"""Multi-subscriber for IItem + IObjectClonedEvent.
"""
# First, do the manage_afterClone dance
- if hasDeprecatedMethods(ob):
- callManageAfterClone(ob, event)
+ callManageAfterClone(ob, event.object)
# Next, dispatch to sublocations
if OFS.interfaces.IObjectManager.providedBy(ob):
dispatchToSublocations(ob, event)
-def callManageAfterAdd(ob, event):
+def callManageAfterAdd(ob, item, container):
"""Compatibility subscriber for manage_afterAdd.
"""
- container = event.newParent
if container is None:
- # this is a remove
return
- ob.manage_afterAdd(event.object, container)
+ if getattr(aq_base(ob), 'manage_afterAdd', None) is None:
+ return
+ maybeWarnDeprecated(ob, 'manage_afterAdd')
+ ob.manage_afterAdd(item, container)
-def callManageBeforeDelete(ob, event):
+def callManageBeforeDelete(ob, item, container):
"""Compatibility subscriber for manage_beforeDelete.
"""
- import OFS.ObjectManager # avoid circular imports
- container = event.oldParent
if container is None:
- # this is an add
return
+ if getattr(aq_base(ob), 'manage_beforeDelete', None) is None:
+ return
+ maybeWarnDeprecated(ob, 'manage_beforeDelete')
+ import OFS.ObjectManager # avoid circular imports
try:
- ob.manage_beforeDelete(event.object, container)
+ ob.manage_beforeDelete(item, container)
except OFS.ObjectManager.BeforeDeleteException:
raise
except ConflictError:
@@ -153,7 +158,10 @@
if not getSecurityManager().getUser().has_role('Manager'):
raise
-def callManageAfterClone(ob, event):
+def callManageAfterClone(ob, item):
"""Compatibility subscriber for manage_afterClone.
"""
- ob.manage_afterClone(event.object)
+ if getattr(aq_base(ob), 'manage_afterClone', None) is None:
+ return
+ maybeWarnDeprecated(ob, 'manage_afterClone')
+ ob.manage_afterClone(item)
Modified: Zope/trunk/lib/python/Products/BTreeFolder2/BTreeFolder2.py
===================================================================
--- Zope/trunk/lib/python/Products/BTreeFolder2/BTreeFolder2.py 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/BTreeFolder2/BTreeFolder2.py 2005-11-10 15:05:07 UTC (rev 40026)
@@ -444,7 +444,7 @@
if not suppress_events:
notify(ObjectAddedEvent(ob, self, id))
- OFS.subscribers.maybeCallDeprecated('manage_afterAdd', ob, self)
+ OFS.subscribers.compatibilityCall('manage_afterAdd', ob, ob, self)
return id
@@ -452,7 +452,7 @@
def _delObject(self, id, dp=1, suppress_events=False):
ob = self._getOb(id)
- OFS.subscribers.maybeCallDeprecated('manage_beforeDelete', ob, self)
+ OFS.subscribers.compatibilityCall('manage_beforeDelete', ob, ob, self)
if not suppress_events:
notify(ObjectWillBeRemovedEvent(ob, self, id))
Modified: Zope/trunk/lib/python/Products/Five/CHANGES.txt
===================================================================
--- Zope/trunk/lib/python/Products/Five/CHANGES.txt 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/CHANGES.txt 2005-11-10 15:05:07 UTC (rev 40026)
@@ -2,6 +2,11 @@
Five Changes
============
+Five 1.3b2 (2005-11-10)
+=======================
+
+This version is included in Zope 2 trunk as of this date.
+
Five 1.3b (2005-11-02)
======================
@@ -36,6 +41,17 @@
components has been removed as that functionality is now in the Zope
2 core as of Zope 2.9.
+Five 1.2 (unreleased)
+=====================
+
+Bugfixes
+--------
+
+* Fixed bug that broke WebDAV access for five:defaultViewable objects. The
+ __browser_default__ now modifies only GET and POST requests.
+
+* Fixed some event recursion compatibility modes.
+
Five 1.2b (2005-11-02)
======================
@@ -74,9 +90,9 @@
* Removed backwards compatibility for Zope 2.7 and 2.8.0.
* Added a (temporarily) forked copy of the "new-and-improved" test
- runner and supporting 'zope.testing' package, lifted from
+ runner and supporting ``zope.testing`` package, lifted from
http://svn.zope.org/zope.testing. This code should be removed for
- Five 1.3, which will use the updated version of 'zope.testing' in
+ Five 1.3, which will use the updated version of ``zope.testing`` in
the Zope 2.9 / Zope 3.2 tree.
There is a test runner invoking script in the ``Five`` package. For
@@ -85,8 +101,8 @@
$ bin/zopectl run Products/Five/runtests.py -v -s Products.Five
-* Moved the 'Five.testing' package down to 'Five.tests.testing', in
- order to make room for the 'zope.testing' code.
+* Moved the ``Five.testing`` package down to ``Five.tests.testing``,
+ in order to make room for the 'zope.testing' code.
* Removed backwards compatibility for some moved classes (AddForm,
EditForm, ContentAdding)
@@ -189,7 +205,7 @@
* The former test product, ``FiveTest``, was converted into separate
modules that provide the mock objects for the corresponding tests
and are located right next to them. Common test helpers have been
- moved to the Five.tests.testing package. Overall, the testing framework
+ moved to the Five.testing package. Overall, the testing framework
was much simplified and the individual tests clean up after
themselves much like they do in Zope 3.
Added: Zope/trunk/lib/python/Products/Five/COPYING.txt
===================================================================
--- Zope/trunk/lib/python/Products/Five/COPYING.txt 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/COPYING.txt 2005-11-10 15:05:07 UTC (rev 40026)
@@ -0,0 +1,16 @@
+Five is distributed under the provisions of the Zope Public License
+(ZPL) v2.1. See doc/ZopePublicLicense.txt for the license text.
+
+Copyright (C) 2005 Five Contributors. See CREDITS.txt for a list of
+Five contributors.
+
+Five contains source code derived from:
+
+- Zope 3, copyright (C) 2001-2005 by Zope Corporation.
+
+- metaclass.py is derived from PEAK, copyright (C) 1996-2004 by
+ Phillip J. Eby and Tyler C. Sarna. PEAK may be used under the same
+ terms as Zope.
+
+- TrustedExecutables. Dieter Mauer kindly allow licensing this under the
+ ZPL 2.1.
Property changes on: Zope/trunk/lib/python/Products/Five/COPYING.txt
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: Zope/trunk/lib/python/Products/Five/INSTALL.txt
===================================================================
--- Zope/trunk/lib/python/Products/Five/INSTALL.txt 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/INSTALL.txt 2005-11-10 15:05:07 UTC (rev 40026)
@@ -0,0 +1,17 @@
+How to install Five
+-------------------
+
+Requirements for Five 1.3
+=========================
+
+* Zope 2.9+ with Python 2.4.1+
+
+Note that Five 1.3 is already part of Zope 2.9. You can still install
+a newer Five version in your instance, if you like. It will override
+the Five product inside the Zope tree.
+
+Running the tests
+=================
+
+For information on how to install the automatic Five tests, please see
+``tests/README.txt``.
Property changes on: Zope/trunk/lib/python/Products/Five/INSTALL.txt
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: Zope/trunk/lib/python/Products/Five/doc/ZopePublicLicense.txt
===================================================================
--- Zope/trunk/lib/python/Products/Five/doc/ZopePublicLicense.txt 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/doc/ZopePublicLicense.txt 2005-11-10 15:05:07 UTC (rev 40026)
@@ -0,0 +1,54 @@
+Zope Public License (ZPL) Version 2.1
+-------------------------------------
+
+A copyright notice accompanies this license document that
+identifies the copyright holders.
+
+This license has been certified as open source. It has also
+been designated as GPL compatible by the Free Software
+Foundation (FSF).
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the
+following conditions are met:
+
+1. Redistributions in source code must retain the
+ accompanying copyright notice, this list of conditions,
+ and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the accompanying
+ copyright notice, this list of conditions, and the
+ following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+3. Names of the copyright holders must not be used to
+ endorse or promote products derived from this software
+ without prior written permission from the copyright
+ holders.
+
+4. The right to distribute this software or to use it for
+ any purpose does not give you the right to use
+ Servicemarks (sm) or Trademarks (tm) of the copyright
+ holders. Use of them is covered by separate agreement
+ with the copyright holders.
+
+5. If any files are modified, you must cause the modified
+ files to carry prominent notices stating that you changed
+ the files and the date of any change.
+
+Disclaimer
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS''
+ AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ NO EVENT SHALL THE COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
Property changes on: Zope/trunk/lib/python/Products/Five/doc/ZopePublicLicense.txt
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: Zope/trunk/lib/python/Products/Five/doc/event.txt
===================================================================
--- Zope/trunk/lib/python/Products/Five/doc/event.txt 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/doc/event.txt 2005-11-10 15:05:07 UTC (rev 40026)
@@ -0,0 +1,287 @@
+Events in Zope 2.9
+==================
+
+Zope 2.9 (and Zope 2.8 when using Five 1.2) introduces a big change:
+Zope 3 style container events.
+
+With container events, you finally have the ability to react to things
+happening to objects without have to subclass ``manage_afterAdd``,
+``manage_beforeDelete`` or ``manage_afterClone``. Instead, you just have
+to register a subscriber for the appropriate event, for instance
+IObjectAddedEvent, and make it do the work.
+
+Indeed, the old methods like ``manage_afterAdd`` are now deprecated, you
+shouldn't use them anymore.
+
+Let's see how to migrate your products.
+
+Old product
+-----------
+
+Suppose that in an old product you have code that needs to register
+through a central tool whenever a document is created. Or it could be
+indexing itself. Or it could initialize an attribute according to its
+current path. Code like::
+
+ class CoolDocument(...):
+ ...
+ def manage_afterAdd(self, item, container):
+ self.mangled_path = mangle('/'.join(self.getPhysicalPath()))
+ getToolByName(self, 'portal_cool').registerCool(self)
+ super(CoolDocument, self).manage_afterAdd(item, container)
+
+ def manage_afterClone(self, item):
+ self.mangled_path = mangle('/'.join(self.getPhysicalPath()))
+ getToolByName(self, 'portal_cool').registerCool(self)
+ super(CoolDocument, self).manage_afterClone(item)
+
+ def manage_beforeDelete(self, item, container):
+ super(CoolDocument, self).manage_beforeDelete(item, container)
+ getToolByName(self, 'portal_cool').unregisterCool(self)
+
+This would be the best practice in Zope 2.8. Note the use of ``super()``
+to call the base class, which is often omitted because people "know"
+that SimpleItem for instance doesn't do anything in these methods.
+
+If you run this code in Zope 2.9, you will get deprecation warnings,
+telling you that::
+
+ Calling Products.CoolProduct.CoolDocument.CoolDocument.manage_afterAdd
+ is deprecated when using Five, instead use event subscribers or mark
+ the class with <five:deprecatedManageAddDelete/>
+
+Using five:deprecatedManageAddDelete
+------------------------------------
+
+The simplest thing you can do to deal with the deprecation warnings, and
+have correct behavior, is to add in your products a ``configure.zcml``
+file containing::
+
+ <configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:five="http://namespaces.zope.org/five">
+
+ <five:deprecatedManageAddDelete
+ class="Products.CoolProduct.CoolDocument.CoolDocument"/>
+
+ </configure>
+
+This tells Zope that you acknowledge that your class contains deprecated
+methods, and ask it to still call them in the proper manner. So Zope
+will be sending events when an object is added, for instance, and in
+addition call your old ``manage_afterAdd`` method.
+
+One subtlety here is that you may have to modify you methods to just do
+their work, and not call their super class. This is necessary because
+proper events are already dispatched to all relevant classes, and the
+work of the super class will be done trough events, you must not redo it
+by hand. If you call the super class, you will get a warning, saying for
+instance::
+
+ CoolDocument.manage_afterAdd is deprecated and will be removed in
+ Zope 2.11, you should use an IObjectAddedEvent subscriber instead.
+
+The fact that you must "just do your work" is especially important for
+the rare cases where people subclass the ``manage_afterAdd`` of object
+managers like folders, and decided to reimplement recursion into the
+children themselves. If you do that, then there will be two recursions
+going on in parallel, the one done by events, and the one done by your
+code. This would be bad.
+
+Using subscribers
+-----------------
+
+In the long run, and before Zope 2.11 where ``manage_afterAdd`` and
+friends will be removed, you will want to use proper subscribers.
+
+First, you'll have to write a subscriber that "does the work", for
+instance::
+
+ def addedCoolDocument(ob, event):
+ """A Cool Document was added to a container."""
+ self.mangled_path = mangle('/'.join(self.getPhysicalPath()))
+
+Note that we're not calling the ``portal_cool`` tool anymore, because
+presumably this tool will also be modified to do its work through
+events, and will have a similar subscriber doing the necessary
+``registerCool``. Note also that here we don't care about the event, but
+in more complex cases we would.
+
+Now we have to register our subscriber for our object. To do that, we
+need to "mark" our object through an interface. We can define in our
+product's ``interfaces.py``::
+
+ from zope.interface import Interface, Attribute
+
+ class ICoolDocument(Interface):
+ """Cool Document."""
+ mangled_path = Attribute("Our mangled path.")
+ ...
+
+Then the class CoolDocument is marked with this interface::
+
+ from zope.interface import implements
+ from Products.CoolProduct.interfaces import ICoolDocument
+ class CoolDocument(...):
+ implements(ICoolDocument)
+ ...
+
+Finally we must link the event and the interface to the subscriber using
+zcml, so in ``configure.zcml`` we'll add::
+
+ ...
+ <subscriber
+ for="Products.CoolProduct.interfaces.ICoolDocument
+ zope.app.container.interfaces.IObjectAddedEvent"
+ handler="Products.CoolProduct.CoolDocument.addedCoolDocument"
+ />
+ ...
+
+And that's it, everything is plugged. Note that IObjectAddedEvent takes
+care of both ``manage_afterAdd`` and ``manage_afterClone``, as it's sent
+whenever a new object is placed into a container. However this won't
+take care of moves and renamings, we'll see below how to do that.
+
+Event dispatching
+-----------------
+
+When an IObjectEvent (from which all the events we're talking here
+derive) is initially sent, it concerns one object. For instance, a
+specific object is removed. The ``event.object`` attribute is this
+object.
+
+To be able to know about removals, we could just subscribe to the
+appropriate event using a standard event subscriber. In that case, we'd
+have to filter "by hand" to check if the object removed is of the type
+we're interested in, which would be a chore. In addition, any subobjects
+of the removed object wouldn't know what happens to them, and for
+instance they wouldn't have any way of doing some cleanup before they
+disappear.
+
+To solve these two problems, Zope 3 has an additional mechanism by which
+any IObjectEvent is redispatched using multi-adapters of the form ``(ob,
+event)``, so that a subscriber can be specific about the type of object
+it's interested in. Furthermore, this is done recursively for all
+sublocations ``ob`` of the initial object. The ``event`` won't change
+though, and ``event.object`` will still be the original object for which
+the event was initially sent (this corresponds to ``self`` and ``item``
+in the ``manage_afterAdd`` method -- ``self`` is ``ob``, and ``item`` is
+``event.object``).
+
+Understanding the hierarchy of events is important to see how to
+subscribe to them.
+
+ * IObjectEvent is the most general. Any event focused on an object
+ derives from this.
+
+ * IObjectMovedEvent is sent when an object changes location or is
+ renamed. It is quite general, as it also encompasses the case where
+ there's no old location (addition) or no new location (removal).
+
+ * IObjectAddedEvent and IObjectRemovedEvent both derive from
+ IObjectMovedEvent.
+
+ * IObjectCopiedEvent is sent just after an object copy is made, but
+ this doesn't mean the object has been put into its new container yet,
+ so it doesn't have a location.
+
+There are only a few basic use cases about what one wants to do with
+respect to events (but you might want to read the full story in
+Five/tests/event.txt).
+
+The first use case is the one where the object has to be aware of its
+path, like in the CoolDocument example above. That's strictly a Zope 2
+concern, as Zope 3 has others ways to deal with this.
+
+In Zope 2 an object has a new path through creation, copy or move
+(rename is a kind of move). The events sent during these three
+operations are varied: creation sends IObjectAddedEvent, copy sends
+IObjectCopiedEvent then IObjectAddedEvent, and move sends
+IObjectMovedEvent.
+
+So to react to new paths, we have to subscribe to IObjectMovedEvent, but
+this will also get us any IObjectRemovedEvent, which we'll have to
+filter out by hand (this is unfortunate, and due to the way the Zope 3
+interface hierarchy is organized). So to fix the CoolDocument
+configuration we have to add::
+
+ def movedCoolDocument(ob, event):
+ """A Cool Document was moved."""
+ if not IObjectRemovedEvent.providedBy(event):
+ addedCoolDocument(ob, event)
+
+And replace the subscriber with::
+
+ ...
+ <subscriber
+ for="Products.CoolProduct.interfaces.ICoolDocument
+ zope.app.container.interfaces.IObjectMovedEvent"
+ handler="Products.CoolProduct.CoolDocument.movedCoolDocument"
+ />
+ ...
+
+The second use case is when the object has to do some cleanup when it is
+removed from its parent. This used to be in ``manage_beforeDelete``, now
+we can do the work in a ``removedCoolDocument`` method and just
+subscribe to IObjectRemovedEvent. But wait, this won't take into account
+moves... So in the same vein as above, we would have to write::
+
+ def movedCoolDocument(ob, event):
+ """A Cool Document was moved."""
+ if not IObjectRemovedEvent.providedBy(event):
+ addedCoolDocument(ob, event)
+ if not IObjectAddedEvent.providedBy(event):
+ removedCoolDocument(ob, event)
+
+The third use case is when your object has to stay registered with some
+tool, for instance indexed in a catalog, or as above registered with
+``portal_cool``. Here we have to know the old object's path to
+unregister it, so we have to be called *before* it is removed. We'll use
+``IObjectWillBe...`` events, that are sent before the actual operations
+take place::
+
+ from OFS.interfaces import IObjectWillBeAddedEvent
+ def beforeMoveCoolDocument(ob, event):
+ """A Cool Document will be moved."""
+ if not IObjectWillBeAddedEvent.providedBy(event):
+ getToolByName(ob, 'portal_cool').unregisterCool(ob)
+
+ def movedCoolDocument(ob, event):
+ """A Cool Document was moved."""
+ if not IObjectRemovedEvent.providedBy(event):
+ getToolByName(ob, 'portal_cool').registerCool(ob)
+ ...
+
+And use an additional subscriber::
+
+ ...
+ <subscriber
+ for="Products.CoolProduct.interfaces.ICoolDocument
+ OFS.interfaces.IObjectWillBeMovedEvent"
+ handler="Products.CoolProduct.CoolDocument.beforeMoveCoolDocument"
+ />
+ ...
+
+This has to be done if the tool cannot react by itself to objects being
+added and removed, which obviously would be better as it's ultimately
+the tool's responsibility and not the object's.
+
+Note that if having tests like::
+
+ if not IObjectWillBeAddedEvent.providedBy(event):
+ if not IObjectRemovedEvent.providedBy(event):
+
+seems cumbersome (and backwards), it is also possible to check what kind
+of event you're dealing with using::
+
+ if event.oldParent is not None:
+ if event.newParent is not None:
+
+(However be careful, the ``oldParent`` and ``newParent`` are the old and
+new parents *of the original object* for which the event was sent, not
+of the one to which the event was redispatched using the
+multi-subscribers we have registered.)
+
+The ``IObjectWillBe...`` events are specific to Zope 2 (and imported
+from ``OFS.interfaces``). Zope 3 doesn't really need them, as object
+identity is often enough.
Property changes on: Zope/trunk/lib/python/Products/Five/doc/event.txt
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: Zope/trunk/lib/python/Products/Five/doc/i18n.txt
===================================================================
--- Zope/trunk/lib/python/Products/Five/doc/i18n.txt 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/doc/i18n.txt 2005-11-10 15:05:07 UTC (rev 40026)
@@ -0,0 +1,76 @@
+Internationalization
+====================
+
+Translation
+-----------
+
+Five registers its own translation service mockup with the Page
+Templates machinery and prevents any other product from also doing so.
+That means, Five always assumes control over ZPT i18n. When a certain
+domain has not been registered the Zope 3 way, Five's translation
+service will see that the utility lookup fails and use the next
+available fallback translation service. In case of no other
+translation service installed, that is just a dummy fallback. In case
+you have Localizer and PTS installed, it falls back to that.
+
+To register Zope 3 style translation domains, use the following ZCML
+statement::
+
+ <i18n:registerTranslations directory="locales" />
+
+where the 'i18n' prefix is bound to the
+http://namespaces.zope.org/i18n namespace identifier. The directory
+(in this case 'locales') should conform to the `standard gettext
+locale directory layout`__.
+
+.. __: http://www.gnu.org/software/gettext/manual/html_chapter/gettext_10.html#SEC148
+
+
+Preferred languages and negotiation
+-----------------------------------
+
+Fallback translation services such as PTS and Localizer have their own
+way of determining the user-preferred languages and negotiating that
+with the available languages in the respective domain. Zope 3
+translation domains typically adapt the request to
+IUserPreferredLanguages to get a list of preferred languages; then
+they use the INegotiator utility to negotiate between the preferred
+and available languages.
+
+The goal of the sprint was to allow both fallback translation services
+(PTS, Localizer) and Zope 3 translation domains come to the same
+conclusion regarding which language should be chosen. The use case is
+that you have a site running Localizer or PTS and a bunch of "old"
+products using either one of those for translation. Now you have an
+additional, "new" Five-based product using Zope 3 translation domains.
+Most of the time, a page contains user messages from more than one
+domain, so you would all domains be translated to the same language.
+
+
+Adjusting behaviour to your environment
+---------------------------------------
+
+The default behaviour for choosing languages in Five is the one of
+Zope 3: analyze the Accept-Language HTTP header and nothing more. In
+addition, Five providees ``IUserPreferredLanguages`` adapters for
+Localizer and PTS that choose languages the exact same way Localizer
+or PTS would. So, if you're using Five in a Localizer-environment,
+you need this in your product's ``overrides.zcml``:
+
+ <adapter
+ for="zope.publisher.interfaces.http.IHTTPRequest"
+ provides="zope.i18n.interfaces.IUserPreferredLanguages"
+ factory="Products.Five.i18n.LocalizerLanguages"
+ />
+
+If you're using PTS:
+
+ <adapter
+ for="zope.publisher.interfaces.http.IHTTPRequest"
+ provides="zope.i18n.interfaces.IUserPreferredLanguages"
+ factory="Products.Five.i18n.PTSLanguages"
+ />
+
+That way Zope 3 translation domains will always come to the same
+conclusion regarding the language as your original translation service
+would.
Property changes on: Zope/trunk/lib/python/Products/Five/doc/i18n.txt
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: Zope/trunk/lib/python/Products/Five/doc/presentations/five.mgp
===================================================================
--- Zope/trunk/lib/python/Products/Five/doc/presentations/five.mgp 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/doc/presentations/five.mgp 2005-11-10 15:05:07 UTC (rev 40026)
@@ -0,0 +1,127 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%deffont "standard" xfont "helvetica-medium-r"
+%deffont "thick" xfont "helvetica-bold-r"
+%deffont "typewriter" xfont "courier-medium-r"
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Default settings per each line numbers.
+%%
+%default 1 area 90 90, leftfill, size 2, fore "gray20", back "white", font "standard", hgap 0
+%default 2 size 7, vgap 10, prefix " ", ccolor "blue"
+%default 3 size 2, bar "gray70", vgap 10
+%default 4 size 5, fore "gray20", vgap 30, prefix " ", font "standard"
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Default settings that are applied to TAB-indented lines.
+%%
+%tab 1 size 5, vgap 40, prefix " ", icon box "red" 50
+%tab 2 size 4, vgap 40, prefix " ", icon arc "yellow" 50
+%tab 3 size 3, vgap 40, prefix " ", icon delta3 "white" 40
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Five - Zope 3 in Zope 2
+
+
+
+
+%center
+Martijn Faassen, Infrae
+faassen at infrae.com
+
+%page
+
+Motto
+
+
+It was the dawn of the third age of Zope. The Five project was a dream given form. Its goal: to use Zope 3 technologies in Zope 2.7 by creating a Zope 2 product where Zope 3 and Zope 2 could work out their differences peacefully.
+
+(Babylon 5 season 1 intro, creatively quoted)
+
+%page
+
+Motto 2
+
+
+The Law of Fives states simply that: ALL THINGS HAPPEN IN FIVES, OR ARE DIVISIBLE BY OR ARE MULTIPLES OF FIVE, OR ARE SOMEHOW DIRECTLY OR INDIRECTLY RELATED TO FIVE.
+
+THE LAW OF FIVES IS NEVER WRONG.
+
+(Principia Discordia)
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+The problem
+
+
+ We're using Zope 2 in production
+
+ Zope 2 is showing its age
+
+ Zope 3 has better ways to do things
+
+ But can't just switch, we have customers!
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Benefits of using Zope 3 in Zope 2
+
+
+ Able to use Zope 3 technologies right away
+
+ Don't reinvent the wheel/APIs
+
+ Better prepared for Zope 3 transition
+
+ Evolution, not revolution
+
+ Convergence, not divergence
+
+%page
+
+What works now?
+
+
+ Interfaces (zope.interface)
+
+ Schema (zope.schema)
+
+ ZCML (zope.configuration)
+
+ Adapters (zope.component)
+
+ Views, including layers, skins (zope.component)
+
+%page
+
+Brief demo
+
+
+ Show ZCML, adapters and views in action
+
+%page
+
+Next?
+
+
+ Utilities (global ones should work)
+
+ Forms
+
+ Views (improve the current system)
+
+ Who knows?
+
+%page
+
+Plans
+
+
+ Relicense from BSD to generic ZPL 2.1
+
+ Move from CVS at Infrae into SVN at codespeak.net
+
+ Convergence; join us!
+
Added: Zope/trunk/lib/python/Products/Five/doc/presentations/five_directions.mgp
===================================================================
--- Zope/trunk/lib/python/Products/Five/doc/presentations/five_directions.mgp 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/doc/presentations/five_directions.mgp 2005-11-10 15:05:07 UTC (rev 40026)
@@ -0,0 +1,88 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%deffont "standard" xfont "helvetica-medium-r"
+%deffont "thick" xfont "helvetica-bold-r"
+%deffont "typewriter" xfont "courier-medium-r"
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Default settings per each line numbers.
+%%
+%default 1 area 90 90, leftfill, size 2, fore "gray20", back "white", font "standard", hgap 0
+%default 2 size 7, vgap 10, prefix " ", ccolor "blue"
+%default 3 size 2, bar "gray70", vgap 10
+%default 4 size 5, fore "gray20", vgap 30, prefix " ", font "standard"
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Default settings that are applied to TAB-indented lines.
+%%
+%tab 1 size 5, vgap 40, prefix " ", icon box "red" 50
+%tab 2 size 4, vgap 40, prefix " ", icon arc "yellow" 50
+%tab 3 size 3, vgap 40, prefix " ", icon delta3 "white" 40
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Five - Zope 3 in Zope 2
+
+
+
+
+%center
+Martijn Faassen, Infrae
+faassen at infrae.com
+Five developer
+
+%page
+
+Five future directions
+
+
+ What might happen
+
+%page
+
+Unique id service support
+
+
+ Foundation is there in form of events
+
+ Unfortunately implementation can not be the same
+
+ Objects are referenced differently in Zope 3
+
+ Local services/utilities are difficult in Zope 2
+
+ Could lead to Zope 3 catalog support
+
+%page
+
+Page template engine improvements
+
+
+ Right now we already use Zope 3 page templates
+
+ These are unicode-only (and work with plain ascii)
+
+ To support Zope 2 content, need classic non-ascii string support
+
+ Issue in Plone, not in Silva (heh heh)
+
+%page
+
+Zope 2.8 and ZODB 3.3
+
+
+ Should be able to work much better with new-style objects
+
+ Things like local services/utilities might be doable
+
+%page
+
+Integration with Plone, CMF, Silva, UnionCMS etc
+
+
+ Sharing a common base is good
+
+ Zope 3 is good
+
+ That base should be Zope 3
+
+ Five can help us start sharing today
Added: Zope/trunk/lib/python/Products/Five/doc/presentations/five_interface_tutorial.mgp
===================================================================
--- Zope/trunk/lib/python/Products/Five/doc/presentations/five_interface_tutorial.mgp 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/doc/presentations/five_interface_tutorial.mgp 2005-11-10 15:05:07 UTC (rev 40026)
@@ -0,0 +1,267 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%deffont "standard" xfont "helvetica-medium-r"
+%deffont "thick" xfont "helvetica-bold-r"
+%deffont "typewriter" xfont "courier-medium-r"
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Default settings per each line numbers.
+%%
+%default 1 area 90 90, leftfill, size 2, fore "gray20", back "white", font "standard", hgap 0
+%default 2 size 7, vgap 10, prefix " ", ccolor "blue"
+%default 3 size 2, bar "gray70", vgap 10
+%default 4 size 5, fore "gray20", vgap 30, prefix " ", font "standard"
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Default settings that are applied to TAB-indented lines.
+%%
+%tab 1 size 5, vgap 40, prefix " ", icon box "red" 50
+%tab 2 size 4, vgap 40, prefix " ", icon arc "yellow" 50
+%tab 3 size 3, vgap 40, prefix " ", icon delta3 "white" 40
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Five - Zope 3 in Zope 2
+
+
+
+
+%center
+Martijn Faassen, Infrae
+faassen at infrae.com
+Five developer
+
+%page
+
+Interfaces, adapters
+
+
+ What are interfaces?
+
+ What are adapters?
+
+ Why?
+
+ A very quick introduction
+
+%page
+
+Actually
+
+
+ This tutorial applies to Zope 3 as much as to Five
+
+ Indication Five reached its goal in this area
+
+%page
+
+Interface example
+
+
+%size 4, fore "blue"
+from zope.interface import Interface
+
+class IElephant(Interface):
+ """An elephant is a big grey animal.
+ """
+ def getAngerLevel():
+ "Return anger level on scale 0 (placid) to 10 (raging)"
+
+ def trample(target):
+ "Trample the target."
+
+ def trumpet():
+ "Make loud noise with trunk."
+
+%page
+
+Interface example, continued
+
+
+%size 4, fore "blue"
+from zope.interface import implements
+
+class AfricanElephant:
+ implements(IElephant)
+
+ def getAngerLevel(self):
+ return 5 # always pretty stroppy
+
+ def trample(self, target):
+ target.flatten()
+
+ def trumpet(self):
+ return "A terrible racket"
+
+%page
+
+Interfaces
+
+
+ Interfaces are about the what, not the how
+
+ Interfaces don't do anything, they just describe
+
+ Code can state what interfaces objects provide
+
+ Code can introspect whether objects provide interfaces
+
+%page
+
+Why interfaces?
+
+
+ They are documentation
+
+ Make multiple implementations of same interface easier
+
+ Allows you to program against published APIs
+
+ Allow glueing by interface
+
+%page
+
+Component architecture
+
+
+ zope.component part of Zope 3
+
+ allows glueing together of components in various ways
+
+ a component is an object which provides an interface
+
+ a Zope 2 object with a Zope 3 interface is a component
+
+%page
+
+Adapters, example
+
+
+%size 4, fore "blue"
+class INoiseMaker(Interface):
+ """Something that makes noise.
+ """
+ def makeNoise():
+ "Returns the noise that's made."
+
+%page
+
+Adapters, example continued
+
+
+%size 4, fore "blue"
+class ElephantNoiseMaker:
+ """Adapts elephant to noise maker.
+ """
+ implements(INoiseMaker)
+
+ def __init__(self, context):
+ self.context = context
+
+ def makeNoise(self):
+ return self.context.trumpet()
+
+%page
+
+Adapters, example continued 2
+
+
+%size 4, fore "blue"
+>>> elephant = AfricanElephant()
+>>> noise_maker = ElephantNoiseMaker(elephant)
+>>> print noise_maker.makeNoise()
+'A terrible racket'
+
+%page
+
+Adapters
+
+
+ Add behavior to object without changing its class
+
+ More manageable than mixins
+
+ Define new behavior in terms of other behavior
+
+%page
+
+Adapters, continued
+
+
+ Less framework burden on adapted objects
+
+ They only need to be a component
+
+ Adapted doesn't know about the adapter
+
+ Adapter is a component itself
+
+%page
+
+Adapter lookup
+
+
+ We just manually glued the adapter to the adapted
+
+ What if we had INoiseMaker adapters for other objects?
+
+ We want a universal way to say: give me a INoiseMaker for this object
+
+ This allows use to write more generic code
+
+%page
+
+Adapter lookup, example
+
+
+%size 4, fore "blue"
+for animal in animal_farm:
+ noise_maker = INoiseMaker(animal)
+ print noise_maker.makeNoise()
+
+%page
+
+Adapter glueing
+
+
+ System need to be informed what can adapt what
+
+ Zope Configuration Markup Language (ZCML) is used for that
+
+%page
+
+ZCML example
+
+
+%size 4, fore "blue"
+<configure xmlns="http://namespaces.zope.org/zope">
+ <adapter
+ for=".module.IElephant"
+ provides=".module.INoiseMaker"
+ factory=".module.ElephantNoiseMaker" />
+ <adapter
+ for=".other.IChicken"
+ provides=".module.INoiseMaker"
+ factory=".other.ChickenNoiseMaker" />
+</configure>
+
+%page
+
+ZCML, what we just said
+
+
+ The adapter ElephantNoiseMaker adapts any object that provides IElephant to a INoiseMaker
+
+ The adapter ChickenNoiseMaker adapts any object that provides IChicken to a INoiseMaker
+
+%page
+
+This works in Zope 2 with Five
+
+
+ This works in Zope 2 with Five
+
+ Your objects just need to be components (provide Zope 3 interfaces)
+
+ Your ZCML goes into configure.zcml in your product
+
+ That's it
Added: Zope/trunk/lib/python/Products/Five/doc/presentations/five_intro.mgp
===================================================================
--- Zope/trunk/lib/python/Products/Five/doc/presentations/five_intro.mgp 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/doc/presentations/five_intro.mgp 2005-11-10 15:05:07 UTC (rev 40026)
@@ -0,0 +1,243 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%deffont "standard" xfont "helvetica-medium-r"
+%deffont "thick" xfont "helvetica-bold-r"
+%deffont "typewriter" xfont "courier-medium-r"
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Default settings per each line numbers.
+%%
+%default 1 area 90 90, leftfill, size 2, fore "gray20", back "white", font "standard", hgap 0
+%default 2 size 7, vgap 10, prefix " ", ccolor "blue"
+%default 3 size 2, bar "gray70", vgap 10
+%default 4 size 5, fore "gray20", vgap 30, prefix " ", font "standard"
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Default settings that are applied to TAB-indented lines.
+%%
+%tab 1 size 5, vgap 40, prefix " ", icon box "red" 50
+%tab 2 size 4, vgap 40, prefix " ", icon arc "yellow" 50
+%tab 3 size 3, vgap 40, prefix " ", icon delta3 "white" 40
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Five - Zope 3 in Zope 2
+
+
+
+
+%center
+Martijn Faassen, Infrae
+faassen at infrae.com
+Five developer
+
+%page
+
+An Introduction to Five
+
+
+ Why Five?
+
+ What is Five?
+
+ Where are we, where are we going?
+
+%page
+
+Motto
+
+
+It was the dawn of the third age of Zope. The Five project was a dream given form. Its goal: to use Zope 3 technologies in Zope 2.7 by creating a Zope 2 product where Zope 3 and Zope 2 could work out their differences peacefully.
+
+(Babylon 5 season 1 intro, creatively quoted)
+
+%page
+
+Motto 2
+
+
+The Law of Fives states simply that: ALL THINGS HAPPEN IN FIVES, OR ARE DIVISIBLE BY OR ARE MULTIPLES OF FIVE, OR ARE SOMEHOW DIRECTLY OR INDIRECTLY RELATED TO FIVE.
+
+THE LAW OF FIVES IS NEVER WRONG.
+
+(Principia Discordia)
+
+%page
+
+The problem
+
+
+ We're using Zope 2 in production
+
+ Zope 2 is showing its age
+
+ Zope 3 has better ways to do things
+
+ But can't just switch, we have codebases, customers!
+
+%page
+
+Benefits of using Zope 3 in Zope 2
+
+
+ Able to use Zope 3 technologies right away
+
+ Don't reinvent the wheel/APIs
+
+ Better prepared for Zope 3 transition
+
+ Evolution, not revolution
+
+ Convergence, not divergence (this is important)
+
+%page
+
+Divergence
+
+
+ Infrae created Silva, Nuxeo CPS, etc
+
+ Everybody else started using Plone (why?!)
+
+ I want to use cool Plone technology
+
+ Silva is cool too, you may want to use it
+
+ I don't want to have to reinvent every wheel (just some)
+
+%page
+
+What's stopping us from sharing?
+
+
+ Zope 2 components are hard to share between apps
+
+ Even CMF components need work to share
+
+ Especially if you don't use CMF... (Silva)
+
+ Zope 2 framework burden is making it hard
+
+ Clean Python code is easier to share
+
+%page
+
+Convergence
+
+
+ Unify our diverse efforts
+
+ Zope 3 allows you to write Python, less framework sacrifices
+
+ Zope 3 allows the glueing of components
+
+ Zope 3 is the future
+
+ Five makes some of the future available today
+
+%page
+
+What works now? - an overview
+
+
+ Interfaces
+
+ Schema
+
+ ZCML
+
+ Adapters
+
+ Views, including layers, skins
+
+%page
+
+What works now, continued
+
+
+ Zope 3 page template engine
+
+ Traversal, resources
+
+ Zope 2 security from ZCML
+
+ Events
+
+ Beginnings of forms machinery
+
+%page
+
+Progress made since June
+
+
+ Initial announcement at Europython
+
+ As promised, moved to SVN at codespeak.net
+
+ Got website, mailing list
+
+ People joined the project
+
+%page
+
+Progress made since June, continued
+
+
+ Lots of excellent contributions!
+
+ Much better view infrastructure (traversal)
+
+ ZCML's interaction with Zope 2 products much improved
+
+ UnionCMS and other projects are starting to use it!
+
+%page
+
+The Zope 3 Base
+
+
+ Five is part of the Zope 3 Base
+
+ Zope 3 Base - All Your Bobobase Are Belong To Us
+
+ Possibly the cutest Zope 3 website anywhere
+
+ http://codespeak.net/z3
+
+%page
+
+Zope 3 Base
+
+
+
+
+
+
+%center
+%image "z3-banner.png"
+
+%page
+
+Zope 3 Base, continued
+
+
+ Second area of Zope 3 related development
+
+ Equivalent of Plone collective, for Zope 3
+
+ More freewheeling than dev.zope.org
+
+ Less freewheeling than Plone collective, however
+
+ Cuter than both
+
+%page
+
+Evolution: Five-ification
+
+
+ Five is not just for new Zope 2 projects
+
+ Five can interoperate with existing Zope 2 applications
+
+ Five in Plone - Flon
+
Added: Zope/trunk/lib/python/Products/Five/doc/presentations/five_misc_tutorial.mgp
===================================================================
--- Zope/trunk/lib/python/Products/Five/doc/presentations/five_misc_tutorial.mgp 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/doc/presentations/five_misc_tutorial.mgp 2005-11-10 15:05:07 UTC (rev 40026)
@@ -0,0 +1,139 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%deffont "standard" xfont "helvetica-medium-r"
+%deffont "thick" xfont "helvetica-bold-r"
+%deffont "typewriter" xfont "courier-medium-r"
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Default settings per each line numbers.
+%%
+%default 1 area 90 90, leftfill, size 2, fore "gray20", back "white", font "standard", hgap 0
+%default 2 size 7, vgap 10, prefix " ", ccolor "blue"
+%default 3 size 2, bar "gray70", vgap 10
+%default 4 size 5, fore "gray20", vgap 30, prefix " ", font "standard"
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Default settings that are applied to TAB-indented lines.
+%%
+%tab 1 size 5, vgap 40, prefix " ", icon box "red" 50
+%tab 2 size 4, vgap 40, prefix " ", icon arc "yellow" 50
+%tab 3 size 3, vgap 40, prefix " ", icon delta3 "white" 40
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Five - Zope 3 in Zope 2
+
+
+
+
+%center
+Martijn Faassen, Infrae
+faassen at infrae.com
+Five developer
+
+%page
+
+Five Misc Topics
+
+
+ A number of as-yet uncategorized Five-related topics
+
+%page
+
+Resources
+
+
+ Various kinds of resources available
+
+ File, image, page template resource
+
+ Accessible through ++resource++ namespace
+
+%page
+
+Resources, example
+
+
+%size 4, fore "blue"
+<browser:resource
+ image="z3base.png"
+ name="z3base.png"
+ permission="zope2.ViewManagementScreens"
+ />
+
+%page
+
+Resources
+
+
+ Any Five traversable object now has can be used to get to resource
+
+ url: path/to/object/++resource++z3base.png
+
+ Jim says this is not exactly Zope 3 as it ruins caching
+
+%page
+
+ZCML
+
+
+ ZCML can optionally be put in etc/site.zcml
+
+ If not, Five will automatically use included zcml
+
+ This zcml is in skel
+
+%page
+
+ZCML continued
+
+
+ ZCML loads any configure.zcml in all products
+
+ This is driven by five:loadProducts in site.zcml
+
+ Overrides are possible in override.zcml
+
+ This is driven by five:loadProductsOverrides in site.zcml
+
+%page
+
+Bridging interfaces
+
+
+ "Bride of Frankenzope"
+
+ Utility functions in bridge.py
+
+ Can convert Zope 2 interface to Zope 3 interface
+
+%page
+
+Events
+
+
+ Can instruct Zope 2 object to send Zope 3 style events using five:sendEvents
+
+ These events sent upon copy/move/rename in Zope 2
+
+ IObjectMovedEvent, IObjectAddedEvent, IObjectCopiedEvent, IObjectRemovedEvent
+
+ Can set up functions to subscribe to these events
+
+%page
+
+Content directive and permissions
+
+
+ Use content directive to declare Zope 2 permissions Zope 3 style
+
+ Declare permissions from ZCML, no more declareProtected()
+
+ Your classes look cleaner as a result
+
+%page
+
+Macros
+
+
+ Zope 3 way to aggregate macros into single object
+
Added: Zope/trunk/lib/python/Products/Five/doc/presentations/five_views_tutorial.mgp
===================================================================
--- Zope/trunk/lib/python/Products/Five/doc/presentations/five_views_tutorial.mgp 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/doc/presentations/five_views_tutorial.mgp 2005-11-10 15:05:07 UTC (rev 40026)
@@ -0,0 +1,277 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%deffont "standard" xfont "helvetica-medium-r"
+%deffont "thick" xfont "helvetica-bold-r"
+%deffont "typewriter" xfont "courier-medium-r"
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Default settings per each line numbers.
+%%
+%default 1 area 90 90, leftfill, size 2, fore "gray20", back "white", font "standard", hgap 0
+%default 2 size 7, vgap 10, prefix " ", ccolor "blue"
+%default 3 size 2, bar "gray70", vgap 10
+%default 4 size 5, fore "gray20", vgap 30, prefix " ", font "standard"
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Default settings that are applied to TAB-indented lines.
+%%
+%tab 1 size 5, vgap 40, prefix " ", icon box "red" 50
+%tab 2 size 4, vgap 40, prefix " ", icon arc "yellow" 50
+%tab 3 size 3, vgap 40, prefix " ", icon delta3 "white" 40
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Five - Zope 3 in Zope 2
+
+
+
+
+%center
+Martijn Faassen, Infrae
+faassen at infrae.com
+Five developer
+
+%page
+
+Views with Five
+
+
+ What are views?
+
+ Why?
+
+ How to make them work?
+
+%page
+
+Actually
+
+
+ This tutorial contains only a few Five specific bits
+
+ Otherwise it applies to Zope 3 as much as to Five
+
+ The Five specific bits are mainly some extra ZCML directives
+
+ These are in their own ZCML namespace
+
+%page
+
+Page example: overview.pt
+
+
+%size 4, fore "blue"
+<html>
+<body>
+<p tal:content="context/objectIds"></p>
+</body>
+</html>
+
+%page
+
+Page example: configure.zcml
+
+
+%size 4, fore "blue"
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser"
+ xmlns:five="http://namespaces.zope.org/five">
+ <five:traversable
+ class="OFS.Folder.Folder"
+ />
+ <browser:page
+ for="OFS.interfaces.IFolder"
+ name="overview.html"
+ template="overview.pt"
+ permission="zope2.ViewManagementScreens"
+ />
+</configure>
+
+%page
+
+What works now
+
+
+ some/folder/overview.html
+
+%page
+
+Hooking up the page, explanation
+
+
+ Much like hooking up an adapter
+
+ Adapter provides new interface (API) for developer
+
+ View provides new interface (UI) for user
+
+ Only five-specific thing is making Folder Zope-3 traversable
+
+ Well, and the Zope 2 permission.
+
+%page
+
+Hooking up a page, with class
+
+
+ We need some helper methods
+
+ Very similar to the way you'd use Python scripts in Zope 2
+
+%page
+
+View class example: overview2.pt
+
+
+%size 4, fore "blue"
+<html>
+<body>
+<p tal:content="view/reversedIds"></p>
+</body>
+</html>
+
+%page
+
+View class example: browser.py
+
+
+%size 4, fore "blue"
+from Products.Five import BrowserView
+
+class Overview(BrowserView):
+ def reversedIds(self):
+ result = []
+ for id in self.context.objectIds():
+ l = list(id)
+ l.reverse()
+ reversed_id = ''.join(l)
+ result.append(reversed_id)
+ return result
+
+%page
+
+Example: configure.zcml
+
+
+%size 4, fore "blue"
+ <browser:page
+ for="OFS.interfaces.IFolder"
+ name="overview2.html"
+ template="overview2.pt"
+ permission="zope2.ViewManagementScreens"
+ class=".browser.Overview"
+ />
+
+%page
+
+A note on security
+
+
+ There is none: both python code and ZPT are trusted
+
+ Only checks are happening on the outside
+
+ Performance benefit
+
+ Advantage of simplicity
+
+%page
+
+Publishing an attribute
+
+
+ Expose python method on view directly to the web
+
+%page
+
+Attribute example: browser.py
+
+
+%size 4, fore "blue"
+ def directlyPublished(self):
+ return "This is directly published"
+
+%page
+
+Attribute example: configure zcml
+
+
+%size 4, fore "blue"
+ <browser:page
+ for="OFS.interfaces.IFolder"
+ name="test.html"
+ class=".browser.Overview"
+ attribute="directlyPublished"
+ permission="zope2.ViewManagementScreens"
+ />
+
+%page
+
+Publishing multiple pages
+
+
+ Convenience directive: browser:pages
+
+%page
+
+Multiple pages example
+
+
+%size 4, fore "blue"
+ <browser:pages
+ for="OFS.interfaces.IFolder"
+ class=".browser.NewExample"
+ permission="zope2.ViewManagementScreens"
+ >
+ <browser:page
+ name="one.html"
+ template="one.pt"
+ />
+ <browser:page
+ name="two.html"
+ attribute="two"
+ />
+ </browser:pages>
+
+%page
+
+Default view for object
+
+
+ We can now set views that are named
+
+ What if we traverse to the object itself?
+
+ Use five:defaultViewable and browser:defaultView
+
+%page
+
+Uh oh
+
+
+ This doesn't seem to work yet with Zope folders. Sidnei, help!
+
+ So we'll try it with a custom SimpleItem-based object
+
+%page
+
+DefaultView example
+
+
+%size 4, fore "blue"
+ <five:defaultViewable class=".democontent.DemoContent" />
+
+ <browser:defaultView
+ for=".democontent.IDemoContent"
+ name="someview.html" />
+
+%page
+
+Conclusions
+
+
+ This works much the same way as Zope 3 does too
+
+ Can supplement existing view systems in Zope 2
+
+ Five specific code is mostly isolated in five:traversable and five:defaultViewable
\ No newline at end of file
Added: Zope/trunk/lib/python/Products/Five/doc/presentations/z3-banner.png
===================================================================
(Binary files differ)
Property changes on: Zope/trunk/lib/python/Products/Five/doc/presentations/z3-banner.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Deleted: Zope/trunk/lib/python/Products/Five/doc/products/ViewsTutorial/www/demoContentAdd.zpt
===================================================================
--- Zope/trunk/lib/python/Products/Five/doc/products/ViewsTutorial/www/demoContentAdd.zpt 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/doc/products/ViewsTutorial/www/demoContentAdd.zpt 2005-11-10 15:05:07 UTC (rev 40026)
@@ -1,45 +0,0 @@
-<h1 tal:replace="structure here/manage_page_header">Header</h1>
-
-<h2 tal:define="form_title string:Add Demo Content"
- tal:replace="structure here/manage_form_title">Form Title</h2>
-
-<p class="form-help">
-Add Demo Content
-</p>
-
-<form action="manage_addDemoContent" method="post">
-<table cellspacing="0" cellpadding="2" border="0">
- <tr>
- <td align="left" valign="top">
- <div class="form-label">
- Id
- </div>
- </td>
- <td align="left" valign="top">
- <input type="text" name="id" size="40" />
- </td>
- </tr>
- <tr>
- <td align="left" valign="top">
- <div class="form-label">
- Title
- </div>
- </td>
- <td align="left" valign="top">
- <input type="text" name="title" size="40" />
- </td>
- </tr>
- <tr>
- <td align="left" valign="top">
- </td>
- <td align="left" valign="top">
- <div class="form-element">
- <input class="form-element" type="submit" name="submit_add"
- value=" Add " />
- </div>
- </td>
- </tr>
-</table>
-</form>
-
-<h1 tal:replace="structure here/manage_page_footer">Footer</h1>
Deleted: Zope/trunk/lib/python/Products/Five/makefile.in
===================================================================
--- Zope/trunk/lib/python/Products/Five/makefile.in 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/makefile.in 2005-11-10 15:05:07 UTC (rev 40026)
@@ -1,31 +0,0 @@
-NAME=Five
-
-PYTHON="/usr/bin/python"
-TMPDIR=~/tmp
-
-CURDIR=~/src/projects/Five
-BASE_DIR=${CURDIR}/..
-SOFTWARE_HOME=~/src/zope/2_7/lib/python
-INSTANCE_HOME=~/src/instance/five
-ZOPE_CONFIG=~/src/instance/five/etc/zope.conf
-Z3=~/src/z3/five
-
-.PHONY : clean test reindent reindent_clean
-.PHONY : default
-
-# default: The default step (invoked when make is called without a target)
-default: clean test
-
-clean :
- find . \( -name '*~' -o -name '*.py[co]' -o -name '*.bak' -o -name '\.#*' \) -exec rm {} \; -print
-
-reindent :
- ~/src/reindent.py -r -v .
-
-test :
- export INSTANCE_HOME=${INSTANCE_HOME}; \
- export SOFTWARE_HOME=${SOFTWARE_HOME}; \
- export PYTHONPATH=${Z3}; \
- export ZOPE_CONFIG=${ZOPE_CONFIG}; \
- cd ${CURDIR}/tests && ${PYTHON} -O runalltests.py
-
Modified: Zope/trunk/lib/python/Products/Five/tests/event.txt
===================================================================
--- Zope/trunk/lib/python/Products/Five/tests/event.txt 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/tests/event.txt 2005-11-10 15:05:07 UTC (rev 40026)
@@ -86,38 +86,69 @@
>>> zcml.load_config('meta.zcml', zope.app.component)
>>> zcml.load_config('event.zcml', Products.Five)
+We need at least one fake deprecated method to tell the compatibility
+framework that component architecture is initialized::
+
+ >>> from Products.Five.eventconfigure import setDeprecatedManageAddDelete
+ >>> class C(object): pass
+ >>> setDeprecatedManageAddDelete(C)
+
Old class
=========
If we use an instance of an old class for which we haven't specified
anything, events are sent and the manage_afterAdd & co methods are
-called but in a "compatibility" way.
+called, but with a deprecation warning::
-Because the bases classes of Zope have been changed to not recurse
-except through the event framework, unexpected behavior may happen
-(however a warning will be sent)::
-
+ >>> sub = MyFolder('sub')
+ >>> folder._setObject('sub', sub)
+ ObjectWillBeAddedEvent sub
+ ObjectAddedEvent sub
+ old manage_afterAdd sub sub folder
+ 'sub'
+ >>> sub = folder.sub
>>> ob = MyContent('dog')
- >>> folder._setObject('dog', ob)
+ >>> sub._setObject('dog', ob)
ObjectWillBeAddedEvent dog
ObjectAddedEvent dog
- old manage_afterAdd dog dog folder
+ old manage_afterAdd dog dog sub
'dog'
-And when we delete the object, manage_beforeDelete is also called and
-events are sent::
+And when we rename the subfolder, manage_beforeDelete is also called
+bottom-up and events are sent::
- >>> folder.manage_delObjects('dog')
- old manage_beforeDelete dog dog folder
- ObjectWillBeRemovedEvent dog
- ObjectRemovedEvent dog
+ >>> folder.manage_renameObject('sub', 'marine')
+ ObjectWillBeMovedEvent sub
+ ObjectWillBeMovedEvent dog
+ old manage_beforeDelete dog sub folder
+ old manage_beforeDelete sub sub folder
+ ObjectMovedEvent marine
+ old manage_afterAdd marine marine folder
+ ObjectMovedEvent dog
+ old manage_afterAdd dog marine folder
+Same thing for clone::
+
+ >>> res = folder.manage_clone(folder.marine, 'tank')
+ ObjectCopiedEvent tank
+ ObjectWillBeAddedEvent tank
+ ObjectWillBeAddedEvent dog
+ ObjectAddedEvent tank
+ old manage_afterAdd tank tank folder
+ ObjectAddedEvent dog
+ old manage_afterAdd dog tank folder
+ ObjectClonedEvent tank
+ old manage_afterClone tank tank
+ ObjectClonedEvent dog
+ old manage_afterClone dog tank
+ >>> res.getId()
+ 'tank'
+
Old class with deprecatedManageAddDelete
========================================
We specifiy that our class is deprecated (using zcml in real life)::
- >>> from Products.Five.eventconfigure import setDeprecatedManageAddDelete
>>> setDeprecatedManageAddDelete(MyContent)
>>> setDeprecatedManageAddDelete(MyFolder)
>>> setDeprecatedManageAddDelete(MyOrderedFolder)
Modified: Zope/trunk/lib/python/Products/Five/tests/test_event.py
===================================================================
--- Zope/trunk/lib/python/Products/Five/tests/test_event.py 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/tests/test_event.py 2005-11-10 15:05:07 UTC (rev 40026)
@@ -13,7 +13,7 @@
##############################################################################
"""Test events triggered by Five
-$Id: test_event.py 14595 2005-07-12 21:26:12Z philikon $
+$Id: test_event.py 19706 2005-11-10 14:05:16Z efge $
"""
import os, sys
if __name__ == '__main__':
@@ -40,11 +40,17 @@
def manage_afterAdd(self, item, container):
print 'old manage_afterAdd %s %s %s' % (self.getId(), item.getId(),
container.getId())
+ super(NotifyBase, self).manage_afterAdd(item, container)
+ manage_afterAdd.__five_method__ = True # Shut up deprecation warnings
def manage_beforeDelete(self, item, container):
+ super(NotifyBase, self).manage_beforeDelete(item, container)
print 'old manage_beforeDelete %s %s %s' % (self.getId(), item.getId(),
container.getId())
+ manage_beforeDelete.__five_method__ = True # Shut up deprecation warnings
def manage_afterClone(self, item):
print 'old manage_afterClone %s %s' % (self.getId(), item.getId())
+ super(NotifyBase, self).manage_afterClone(item)
+ manage_afterClone.__five_method__ = True # Shut up deprecation warnings
class MyApp(Folder):
def getPhysicalRoot(self):
Modified: Zope/trunk/lib/python/Products/Five/tests/test_viewable.py
===================================================================
--- Zope/trunk/lib/python/Products/Five/tests/test_viewable.py 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/tests/test_viewable.py 2005-11-10 15:05:07 UTC (rev 40026)
@@ -13,7 +13,7 @@
##############################################################################
"""Unit tests for the viewable module.
-$Id: test_viewable.py 14595 2005-07-12 21:26:12Z philikon $
+$Id: test_viewable.py 19646 2005-11-08 15:46:36Z yuppie $
"""
import os, sys
if __name__ == '__main__':
@@ -77,8 +77,14 @@
"""
def test_suite():
- from Testing.ZopeTestCase import ZopeDocTestSuite
- return ZopeDocTestSuite()
+ import unittest
+ from zope.testing.doctest import DocTestSuite
+ from Testing.ZopeTestCase import FunctionalDocFileSuite
+ return unittest.TestSuite((
+ DocTestSuite(),
+ FunctionalDocFileSuite('viewable.txt',
+ package="Products.Five.tests",),
+ ))
if __name__ == '__main__':
framework()
Added: Zope/trunk/lib/python/Products/Five/tests/viewable.txt
===================================================================
--- Zope/trunk/lib/python/Products/Five/tests/viewable.txt 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/tests/viewable.txt 2005-11-10 15:05:07 UTC (rev 40026)
@@ -0,0 +1,132 @@
+Testing defaultViewable
+=======================
+
+ >>> import Products.Five
+ >>> from Products.Five import zcml
+ >>> zcml.load_config('configure.zcml', package=Products.Five)
+
+PROPFIND without defaultViewable
+--------------------------------
+
+ >>> print http(r"""
+ ... PROPFIND /test_folder_1_ HTTP/1.1
+ ... Authorization: Basic test_user_1_:secret
+ ... Content-Length: 250
+ ... Content-Type: application/xml
+ ... Depth: 1
+ ...
+ ... <?xml version="1.0" encoding="utf-8"?>
+ ... <propfind xmlns="DAV:"><prop>
+ ... <getlastmodified xmlns="DAV:"/>
+ ... <creationdate xmlns="DAV:"/>
+ ... <resourcetype xmlns="DAV:"/>
+ ... <getcontenttype xmlns="DAV:"/>
+ ... <getcontentlength xmlns="DAV:"/>
+ ... </prop></propfind>
+ ... """, handle_errors=False)
+ HTTP/1.1 207 Multi-Status
+ Connection: close
+ Content-Length: ...
+ Content-Location: http://localhost/test_folder_1_/
+ Content-Type: text/xml; charset="utf-8"
+ Date: ...
+ <BLANKLINE>
+ <?xml version="1.0" encoding="utf-8"?>
+ <d:multistatus xmlns:d="DAV:">
+ <d:response>
+ <d:href>/test_folder_1_/</d:href>
+ <d:propstat>
+ <d:prop>
+ <n:getlastmodified xmlns:n="DAV:">...
+ <n:creationdate xmlns:n="DAV:">...
+ <n:resourcetype xmlns:n="DAV:"><n:collection/></n:resourcetype>
+ <n:getcontenttype xmlns:n="DAV:"></n:getcontenttype>
+ <n:getcontentlength xmlns:n="DAV:"></n:getcontentlength>
+ </d:prop>
+ <d:status>HTTP/1.1 200 OK</d:status>
+ </d:propstat>
+ </d:response>
+ <d:response>
+ <d:href>/test_folder_1_/acl_users</d:href>
+ <d:propstat>
+ <d:prop>
+ <n:getlastmodified xmlns:n="DAV:">...
+ <n:creationdate xmlns:n="DAV:">...
+ <n:resourcetype xmlns:n="DAV:"></n:resourcetype>
+ <n:getcontenttype xmlns:n="DAV:"></n:getcontenttype>
+ <n:getcontentlength xmlns:n="DAV:"></n:getcontentlength>
+ </d:prop>
+ <d:status>HTTP/1.1 200 OK</d:status>
+ </d:propstat>
+ </d:response>
+ </d:multistatus>
+
+PROPFIND with defaultViewable
+-----------------------------
+
+Now make the class default viewable:
+
+ >>> from Products.Five.fiveconfigure import classDefaultViewable
+ >>> from OFS.Folder import Folder
+ >>> classDefaultViewable(Folder)
+
+And try it again:
+
+ >>> print http(r"""
+ ... PROPFIND /test_folder_1_ HTTP/1.1
+ ... Authorization: Basic test_user_1_:secret
+ ... Content-Length: 250
+ ... Content-Type: application/xml
+ ... Depth: 1
+ ...
+ ... <?xml version="1.0" encoding="utf-8"?>
+ ... <propfind xmlns="DAV:"><prop>
+ ... <getlastmodified xmlns="DAV:"/>
+ ... <creationdate xmlns="DAV:"/>
+ ... <resourcetype xmlns="DAV:"/>
+ ... <getcontenttype xmlns="DAV:"/>
+ ... <getcontentlength xmlns="DAV:"/>
+ ... </prop></propfind>
+ ... """, handle_errors=False)
+ HTTP/1.1 207 Multi-Status
+ Connection: close
+ Content-Length: ...
+ Content-Location: http://localhost/test_folder_1_/
+ Content-Type: text/xml; charset="utf-8"
+ Date: ...
+ <BLANKLINE>
+ <?xml version="1.0" encoding="utf-8"?>
+ <d:multistatus xmlns:d="DAV:">
+ <d:response>
+ <d:href>/test_folder_1_/</d:href>
+ <d:propstat>
+ <d:prop>
+ <n:getlastmodified xmlns:n="DAV:">...
+ <n:creationdate xmlns:n="DAV:">...
+ <n:resourcetype xmlns:n="DAV:"><n:collection/></n:resourcetype>
+ <n:getcontenttype xmlns:n="DAV:"></n:getcontenttype>
+ <n:getcontentlength xmlns:n="DAV:"></n:getcontentlength>
+ </d:prop>
+ <d:status>HTTP/1.1 200 OK</d:status>
+ </d:propstat>
+ </d:response>
+ <d:response>
+ <d:href>/test_folder_1_/acl_users</d:href>
+ <d:propstat>
+ <d:prop>
+ <n:getlastmodified xmlns:n="DAV:">...
+ <n:creationdate xmlns:n="DAV:">...
+ <n:resourcetype xmlns:n="DAV:"></n:resourcetype>
+ <n:getcontenttype xmlns:n="DAV:"></n:getcontenttype>
+ <n:getcontentlength xmlns:n="DAV:"></n:getcontentlength>
+ </d:prop>
+ <d:status>HTTP/1.1 200 OK</d:status>
+ </d:propstat>
+ </d:response>
+ </d:multistatus>
+
+Clean up
+--------
+
+ >>> from zope.app.testing.placelesssetup import tearDown
+ >>> tearDown()
Property changes on: Zope/trunk/lib/python/Products/Five/tests/viewable.txt
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Modified: Zope/trunk/lib/python/Products/Five/version.txt
===================================================================
--- Zope/trunk/lib/python/Products/Five/version.txt 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/version.txt 2005-11-10 15:05:07 UTC (rev 40026)
@@ -1 +1 @@
-Five 1.3b
+Five 1.3b2
Modified: Zope/trunk/lib/python/Products/Five/viewable.py
===================================================================
--- Zope/trunk/lib/python/Products/Five/viewable.py 2005-11-10 13:41:49 UTC (rev 40025)
+++ Zope/trunk/lib/python/Products/Five/viewable.py 2005-11-10 15:05:07 UTC (rev 40026)
@@ -13,7 +13,7 @@
##############################################################################
"""Machinery for making things viewable
-$Id: viewable.py 14595 2005-07-12 21:26:12Z philikon $
+$Id: viewable.py 19646 2005-11-08 15:46:36Z yuppie $
"""
import inspect
from zExceptions import NotFound
@@ -48,6 +48,8 @@
def __browser_default__(self, request):
obj = self
path = None
+ if request['REQUEST_METHOD'] not in ('GET', 'POST'):
+ return obj, [request['REQUEST_METHOD']]
try:
obj, path = IBrowserDefault(self).defaultView(request)
except ComponentLookupError:
More information about the Zope-Checkins
mailing list