[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