[Checkins] SVN: z3c.traverser/tags/0.2.4/ Tag 0.2.4

Dan Korostelev nadako at gmail.com
Mon Feb 2 10:44:41 EST 2009


Log message for revision 95984:
  Tag 0.2.4

Changed:
  A   z3c.traverser/tags/0.2.4/
  U   z3c.traverser/tags/0.2.4/CHANGES.txt
  D   z3c.traverser/tags/0.2.4/README.txt
  A   z3c.traverser/tags/0.2.4/README.txt
  D   z3c.traverser/tags/0.2.4/setup.py
  A   z3c.traverser/tags/0.2.4/setup.py
  D   z3c.traverser/tags/0.2.4/src/
  A   z3c.traverser/tags/0.2.4/src/
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/DEPENDENCIES.cfg
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/README.txt
  A   z3c.traverser/tags/0.2.4/src/z3c/traverser/README.txt
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/browser.py
  A   z3c.traverser/tags/0.2.4/src/z3c/traverser/browser.py
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/README.txt
  A   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/README.txt
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/SETUP.cfg
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/consumer.py
  A   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/consumer.py
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/ftesting.zcml
  A   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/ftesting.zcml
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/configure.zcml
  A   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/configure.zcml
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/consumer.py
  A   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/consumer.py
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/views.py
  A   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/views.py
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/tests.py
  A   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/tests.py
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/traversing.py
  A   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/traversing.py
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/z3c.traverser.stackinfo-configure.zcml
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/browser.py
  A   z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/browser.py
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/ftesting.zcml
  A   z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/ftesting.zcml
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/namespace.py
  A   z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/namespace.py
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/test.pt
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/testing.py
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/tests.py
  A   z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/tests.py
  D   z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/z3c.traverser.viewlet-configure.zcml

-=-
Modified: z3c.traverser/tags/0.2.4/CHANGES.txt
===================================================================
--- z3c.traverser/trunk/CHANGES.txt	2009-02-02 15:11:34 UTC (rev 95978)
+++ z3c.traverser/tags/0.2.4/CHANGES.txt	2009-02-02 15:44:41 UTC (rev 95984)
@@ -2,7 +2,7 @@
 CHANGES
 =======
 
-0.2.4 (unreleased)
+0.2.4 (2009-02-02)
 ------------------
 
 - Make ``PluggableBrowserTraverser`` implement ``IBrowserPublisher``

Deleted: z3c.traverser/tags/0.2.4/README.txt
===================================================================
--- z3c.traverser/trunk/README.txt	2009-02-02 15:11:34 UTC (rev 95978)
+++ z3c.traverser/tags/0.2.4/README.txt	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,10 +0,0 @@
-Traversers are Zope's mechanism to convert URI paths to an object of the
-application. They provide an extremly flexible mechanism to make decisions
-based on the policies of the application. Unfortunately the default traverser
-implementation is not flexible enough to deal with arbitrary extensions (via
-adapters) of objects that also wish to participate in the traversal decision
-process.
-
-The pluggable traverser allows developers, especially third-party developers,
-to add new traversers to an object without altering the original traversal
-implementation.

Copied: z3c.traverser/tags/0.2.4/README.txt (from rev 95981, z3c.traverser/trunk/README.txt)
===================================================================
--- z3c.traverser/tags/0.2.4/README.txt	                        (rev 0)
+++ z3c.traverser/tags/0.2.4/README.txt	2009-02-02 15:44:41 UTC (rev 95984)
@@ -0,0 +1,12 @@
+This package provides the pluggable traverser mechanism allowing developers
+to add new traversers to an object without altering the original traversal
+implementation.
+
+In addition to the pluggable traversers, this package contains two more
+subpackages:
+
+ * viewlet - provides a way to traverse to viewlets using namespaces
+ 
+ * stackinfo - provides a way to consume parts of url and store them
+   as attributes of the "consumer" object. Useful for urls like:
+   /blog/2009/02/02/hello-world

Deleted: z3c.traverser/tags/0.2.4/setup.py
===================================================================
--- z3c.traverser/trunk/setup.py	2009-02-02 15:11:34 UTC (rev 95978)
+++ z3c.traverser/tags/0.2.4/setup.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,82 +0,0 @@
-###############################################################################
-#
-# Copyright (c) 2007 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Setup for z3c.traverser package
-
-$Id: setup.py 81038 2007-10-24 14:34:17Z srichter $
-"""
-import os
-from setuptools import setup, find_packages
-
-def read(*rnames):
-    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
-
-setup(name='z3c.traverser',
-      version = '0.2.4dev',
-      author='Zope Corporation and Contributors',
-      author_email='zope-dev at zope.org',
-      description='Pluggable Traverser API',
-      long_description=(
-          read('README.txt')
-          + '\n\n' +
-          'Detailed Documentation\n' +
-          '======================\n'
-          + '\n\n' +
-          read('src', 'z3c', 'traverser', 'README.txt')
-          + '\n\n' +
-          read('src', 'z3c', 'traverser', 'namespace.txt')
-          + '\n\n' +
-          read('src', 'z3c', 'traverser', 'viewlet', 'README.txt')
-          + '\n\n' +
-          read('src', 'z3c', 'traverser', 'viewlet', 'BROWSER.txt')
-          + '\n\n' +
-          read('src', 'z3c', 'traverser', 'stackinfo', 'README.txt')
-          + '\n\n' +
-          read('src', 'z3c', 'traverser', 'stackinfo', 'BROWSER.txt')
-          + '\n\n' +
-          read('CHANGES.txt')
-          ),
-      keywords = "zope3 traverser pluggable plugin viewlet",
-      classifiers = [
-          'Development Status :: 5 - Production/Stable',
-          'Environment :: Web Environment',
-          'Intended Audience :: Developers',
-          'License :: OSI Approved :: Zope Public License',
-          'Programming Language :: Python',
-          'Natural Language :: English',
-          'Operating System :: OS Independent',
-          'Topic :: Internet :: WWW/HTTP',
-          'Framework :: Zope3'],
-      url='http://pypi.python.org/pypi/z3c.traverser',
-      license='ZPL 2.1',
-      packages=find_packages('src'),
-      package_dir = {'': 'src'},
-      namespace_packages=['z3c'],
-      extras_require = dict(
-          test = ('zope.app.testing',
-                  'zope.app.securitypolicy',
-                  'zope.app.zcmlfiles',
-                  'zope.testbrowser'),
-          ),
-      install_requires=(
-          'setuptools',
-          'zope.component',
-          'zope.contentprovider',
-          'zope.interface',
-          'zope.publisher',
-          'zope.traversing',
-          'zope.viewlet',
-          ),
-      include_package_data = True,
-      zip_safe = False,
-      )

Copied: z3c.traverser/tags/0.2.4/setup.py (from rev 95981, z3c.traverser/trunk/setup.py)
===================================================================
--- z3c.traverser/tags/0.2.4/setup.py	                        (rev 0)
+++ z3c.traverser/tags/0.2.4/setup.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -0,0 +1,82 @@
+###############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Setup for z3c.traverser package
+
+$Id: setup.py 81038 2007-10-24 14:34:17Z srichter $
+"""
+import os
+from setuptools import setup, find_packages
+
+def read(*rnames):
+    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+setup(name='z3c.traverser',
+      version = '0.2.4',
+      author='Zope Corporation and Contributors',
+      author_email='zope-dev at zope.org',
+      description='Pluggable Traversers And URL handling utilities',
+      long_description=(
+          read('README.txt')
+          + '\n\n' +
+          'Detailed Documentation\n' +
+          '======================\n'
+          + '\n\n' +
+          read('src', 'z3c', 'traverser', 'README.txt')
+          + '\n\n' +
+          read('src', 'z3c', 'traverser', 'namespace.txt')
+          + '\n\n' +
+          read('src', 'z3c', 'traverser', 'viewlet', 'README.txt')
+          + '\n\n' +
+          read('src', 'z3c', 'traverser', 'viewlet', 'BROWSER.txt')
+          + '\n\n' +
+          read('src', 'z3c', 'traverser', 'stackinfo', 'README.txt')
+          + '\n\n' +
+          read('src', 'z3c', 'traverser', 'stackinfo', 'BROWSER.txt')
+          + '\n\n' +
+          read('CHANGES.txt')
+          ),
+      keywords = "zope3 traverser pluggable plugin viewlet",
+      classifiers = [
+          'Development Status :: 5 - Production/Stable',
+          'Environment :: Web Environment',
+          'Intended Audience :: Developers',
+          'License :: OSI Approved :: Zope Public License',
+          'Programming Language :: Python',
+          'Natural Language :: English',
+          'Operating System :: OS Independent',
+          'Topic :: Internet :: WWW/HTTP',
+          'Framework :: Zope3'],
+      url='http://pypi.python.org/pypi/z3c.traverser',
+      license='ZPL 2.1',
+      packages=find_packages('src'),
+      package_dir = {'': 'src'},
+      namespace_packages=['z3c'],
+      extras_require = dict(
+          test = ('zope.app.testing',
+                  'zope.app.securitypolicy',
+                  'zope.app.zcmlfiles',
+                  'zope.testbrowser'),
+          ),
+      install_requires=(
+          'setuptools',
+          'zope.component',
+          'zope.contentprovider',
+          'zope.interface',
+          'zope.publisher',
+          'zope.traversing',
+          'zope.viewlet',
+          ),
+      include_package_data = True,
+      zip_safe = False,
+      )

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/DEPENDENCIES.cfg
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/DEPENDENCIES.cfg	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/DEPENDENCIES.cfg	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1 +0,0 @@
-zope.app

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/README.txt
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/README.txt	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/README.txt	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,251 +0,0 @@
-====================
-Pluggable Traversers
-====================
-
-Traversers are Zope's mechanism to convert URI paths to an object of the
-application. They provide an extremly flexible mechanism to make decisions
-based on the policies of the application. Unfortunately the default traverser
-implementation is not flexible enough to deal with arbitrary extensions (via
-adapters) of objects that also wish to participate in the traversal decision
-process.
-
-The pluggable traverser allows developers, especially third-party developers,
-to add new traversers to an object without altering the original traversal
-implementation.
-
-    >>> from z3c.traverser.traverser import PluggableTraverser
-
-Let's say that we have an object
-
-    >>> from zope.interface import Interface, implements
-    >>> class IContent(Interface):
-    ...     pass
-
-    >>> class Content(object):
-    ...     implements(IContent)
-    ...     var = True
-
-    >>> content = Content()
-
-that we wish to traverse to. Since traversers are presentation-type specific,
-they are implemented as views and must thus be initiated using a request:
-
-    >>> from zope.publisher.base import TestRequest
-    >>> request = TestRequest('')
-    >>> traverser = PluggableTraverser(content, request)
-
-We can now try to lookup the variable:
-
-    >>> traverser.publishTraverse(request, 'var')
-    Traceback (most recent call last):
-    ...
-    NotFound: Object: <Content object at ...>, name: 'var'
-
-But it failed. Why? Because we have not registered a plugin traverser yet that
-knows how to lookup attributes. This package provides such a traverser
-already, so we just have to register it:
-
-    >>> from zope.component import provideSubscriptionAdapter
-    >>> from zope.publisher.interfaces import IPublisherRequest
-    >>> from z3c.traverser.traverser import AttributeTraverserPlugin
-
-    >>> provideSubscriptionAdapter(AttributeTraverserPlugin,
-    ...                            (IContent, IPublisherRequest))
-
-If we now try to lookup the attribute, we the value:
-
-    >>> traverser.publishTraverse(request, 'var')
-    True
-
-However, an incorrect variable name will still return a ``NotFound`` error:
-
-    >>> traverser.publishTraverse(request, 'bad')
-    Traceback (most recent call last):
-    ...
-    NotFound: Object: <Content object at ...>, name: 'bad'
-
-Every traverser should also make sure that the passed in name is not a
-view. (This allows us to not specify the ``@@`` in front of a view.) So let's
-register one:
-
-    >>> class View(object):
-    ...     def __init__(self, context, request):
-    ...         pass
-
-    >>> from zope.component import provideAdapter
-    >>> from zope.publisher.interfaces import IPublisherRequest
-    >>> provideAdapter(View,
-    ...                adapts=(IContent, IPublisherRequest),
-    ...                provides=Interface,
-    ...                name='view.html')
-
-Now we can lookup the view as well:
-
-    >>> traverser.publishTraverse(request, 'view.html')
-    <View object at ...>
-
-
-Advanced Uses
--------------
-
-A more interesting case to consider is a traverser for a container. If you
-really dislike the Zope 3 traversal namespace notation ``++namespace++`` and
-you can control the names in the container, then the pluggable traverser will
-also provide a viable solution. Let's say we have a container
-
-    >>> from zope.app.container.interfaces import IContainer
-    >>> class IMyContainer(IContainer):
-    ...     pass
-
-    >>> from zope.app.container.btree import BTreeContainer
-    >>> class MyContainer(BTreeContainer):
-    ...     implements(IMyContainer)
-    ...     foo = True
-    ...     bar = False
-
-    >>> myContainer = MyContainer()
-    >>> myContainer['blah'] = 123
-
-and we would like to be able to traverse
-
-  * all items of the container, as well as
-
-    >>> from z3c.traverser.traverser import ContainerTraverserPlugin
-    >>> from z3c.traverser.interfaces import ITraverserPlugin
-
-    >>> provideSubscriptionAdapter(ContainerTraverserPlugin,
-    ...                            (IMyContainer, IPublisherRequest),
-    ...                            ITraverserPlugin)
-
-  * the ``foo`` attribute. Luckily we also have a predeveloped traverser for
-    this:
-
-    >>> from z3c.traverser.traverser import \
-    ...     SingleAttributeTraverserPlugin
-    >>> provideSubscriptionAdapter(SingleAttributeTraverserPlugin('foo'),
-    ...                            (IMyContainer, IPublisherRequest))
-
-We can now use the pluggable traverser
-
-    >>> traverser = PluggableTraverser(myContainer, request)
-
-to look up items
-
-    >>> traverser.publishTraverse(request, 'blah')
-    123
-
-and the ``foo`` attribute:
-
-    >>> traverser.publishTraverse(request, 'foo')
-    True
-
-However, we cannot lookup the ``bar`` attribute or any other non-existent
-item:
-
-    >>> traverser.publishTraverse(request, 'bar')
-    Traceback (most recent call last):
-    ...
-    NotFound: Object: <MyContainer object at ...>, name: 'bar'
-
-    >>> traverser.publishTraverse(request, 'bad')
-    Traceback (most recent call last):
-    ...
-    NotFound: Object: <MyContainer object at ...>, name: 'bad'
-
-You can also add traversers that return an adapted object. For example, let's
-take the following adapter:
-
-    >>> class ISomeAdapter(Interface):
-    ...     pass
-
-    >>> from zope.component import adapts
-    >>> class SomeAdapter(object):
-    ...     implements(ISomeAdapter)
-    ...     adapts(IMyContainer)
-    ...
-    ...     def __init__(self, context):
-    ...         pass
-
-    >>> from zope.component import adapts, provideAdapter
-    >>> provideAdapter(SomeAdapter)
-
-Now we register this adapter under the traversal name ``some``:
-
-    >>> from z3c.traverser.traverser import AdapterTraverserPlugin
-    >>> provideSubscriptionAdapter(
-    ...     AdapterTraverserPlugin('some', ISomeAdapter),
-    ...     (IMyContainer, IPublisherRequest))
-
-So here is the result:
-
-    >>> traverser.publishTraverse(request, 'some')
-    <SomeAdapter object at ...>
-
-
-Traverser Plugins
------------------
-
-The `traverser` package comes with several default traverser plugins; three of
-them were already introduced above: `SingleAttributeTraverserPlugin`,
-`AdapterTraverserPlugin`, and `ContainerTraverserPlugin`. Another plugin is
-the the `NullTraverserPlugin`, which always just returns the object itself:
-
-    >>> from z3c.traverser.traverser import NullTraverserPlugin
-    >>> SomethingPlugin = NullTraverserPlugin('something')
-
-    >>> plugin = SomethingPlugin(content, request)
-    >>> plugin.publishTraverse(request, 'something')
-    <Content object at ...>
-
-    >>> plugin.publishTraverse(request, 'something else')
-    Traceback (most recent call last):
-    ...
-    NotFound: Object: <Content object at ...>, name: 'something else'
-
-All of the above traversers with exception of the `ContainerTraverserPlugin`
-are realizations of the abstract `NameTraverserPlugin` class. Name traversers
-are traversers that can resolve one particular name. By using the abstract
-`NameTraverserPlugin` class, all of the traverser boilerplate can be
-avoided. Here is a simple example that always returns a specific value for a
-traversed name:
-
-    >>> from z3c.traverser.traverser import NameTraverserPlugin
-    >>> class TrueTraverserPlugin(NameTraverserPlugin):
-    ...     traversalName = 'true'
-    ...     def _traverse(self, request, name):
-    ...         return True
-
-As you can see realized name traversers must implement the ``_traverse()``
-method, which is only responsible for returning the result. Of course it can
-also raise the `NotFound` error if something goes wrong during the
-computation. LEt's check it out:
-
-    >>> plugin = TrueTraverserPlugin(content, request)
-    >>> plugin.publishTraverse(request, 'true')
-    True
-
-    >>> plugin.publishTraverse(request, 'false')
-    Traceback (most recent call last):
-    ...
-    NotFound: Object: <Content object at ...>, name: 'false'
-
-A final traverser that is offered by the package is the
-`AttributeTraverserPlugin``, which simply allows one to traverse all
-accessible attributes of an object:
-
-    >>> from z3c.traverser.traverser import AttributeTraverserPlugin
-
-    >>> plugin = AttributeTraverserPlugin(myContainer, request)
-    >>> plugin.publishTraverse(request, 'foo')
-    True
-    >>> plugin.publishTraverse(request, 'bar')
-    False
-    >>> plugin.publishTraverse(request, 'blah')
-    Traceback (most recent call last):
-    ...
-    NotFound: Object: <MyContainer object at ...>, name: 'blah'
-    >>> plugin.publishTraverse(request, 'some')
-    Traceback (most recent call last):
-    ...
-    NotFound: Object: <MyContainer object at ...>, name: 'some'
-

Copied: z3c.traverser/tags/0.2.4/src/z3c/traverser/README.txt (from rev 95978, z3c.traverser/trunk/src/z3c/traverser/README.txt)
===================================================================
--- z3c.traverser/tags/0.2.4/src/z3c/traverser/README.txt	                        (rev 0)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/README.txt	2009-02-02 15:44:41 UTC (rev 95984)
@@ -0,0 +1,282 @@
+====================
+Pluggable Traversers
+====================
+
+Traversers are Zope's mechanism to convert URI paths to an object of the
+application. They provide an extremly flexible mechanism to make decisions
+based on the policies of the application. Unfortunately the default traverser
+implementation is not flexible enough to deal with arbitrary extensions (via
+adapters) of objects that also wish to participate in the traversal decision
+process.
+
+The pluggable traverser allows developers, especially third-party developers,
+to add new traversers to an object without altering the original traversal
+implementation.
+
+    >>> from z3c.traverser.traverser import PluggableTraverser
+
+Let's say that we have an object
+
+    >>> from zope.interface import Interface, implements
+    >>> class IContent(Interface):
+    ...     pass
+
+    >>> class Content(object):
+    ...     implements(IContent)
+    ...     var = True
+
+    >>> content = Content()
+
+that we wish to traverse to. Since traversers are presentation-type specific,
+they are implemented as views and must thus be initiated using a request:
+
+    >>> from zope.publisher.base import TestRequest
+    >>> request = TestRequest('')
+    >>> traverser = PluggableTraverser(content, request)
+
+We can now try to lookup the variable:
+
+    >>> traverser.publishTraverse(request, 'var')
+    Traceback (most recent call last):
+    ...
+    NotFound: Object: <Content object at ...>, name: 'var'
+
+But it failed. Why? Because we have not registered a plugin traverser yet that
+knows how to lookup attributes. This package provides such a traverser
+already, so we just have to register it:
+
+    >>> from zope.component import provideSubscriptionAdapter
+    >>> from zope.publisher.interfaces import IPublisherRequest
+    >>> from z3c.traverser.traverser import AttributeTraverserPlugin
+
+    >>> provideSubscriptionAdapter(AttributeTraverserPlugin,
+    ...                            (IContent, IPublisherRequest))
+
+If we now try to lookup the attribute, we the value:
+
+    >>> traverser.publishTraverse(request, 'var')
+    True
+
+However, an incorrect variable name will still return a ``NotFound`` error:
+
+    >>> traverser.publishTraverse(request, 'bad')
+    Traceback (most recent call last):
+    ...
+    NotFound: Object: <Content object at ...>, name: 'bad'
+
+Every traverser should also make sure that the passed in name is not a
+view. (This allows us to not specify the ``@@`` in front of a view.) So let's
+register one:
+
+    >>> class View(object):
+    ...     def __init__(self, context, request):
+    ...         pass
+
+    >>> from zope.component import provideAdapter
+    >>> from zope.publisher.interfaces import IPublisherRequest
+    >>> provideAdapter(View,
+    ...                adapts=(IContent, IPublisherRequest),
+    ...                provides=Interface,
+    ...                name='view.html')
+
+Now we can lookup the view as well:
+
+    >>> traverser.publishTraverse(request, 'view.html')
+    <View object at ...>
+
+
+Advanced Uses
+-------------
+
+A more interesting case to consider is a traverser for a container. If you
+really dislike the Zope 3 traversal namespace notation ``++namespace++`` and
+you can control the names in the container, then the pluggable traverser will
+also provide a viable solution. Let's say we have a container
+
+    >>> from zope.app.container.interfaces import IContainer
+    >>> class IMyContainer(IContainer):
+    ...     pass
+
+    >>> from zope.app.container.btree import BTreeContainer
+    >>> class MyContainer(BTreeContainer):
+    ...     implements(IMyContainer)
+    ...     foo = True
+    ...     bar = False
+
+    >>> myContainer = MyContainer()
+    >>> myContainer['blah'] = 123
+
+and we would like to be able to traverse
+
+  * all items of the container, as well as
+
+    >>> from z3c.traverser.traverser import ContainerTraverserPlugin
+    >>> from z3c.traverser.interfaces import ITraverserPlugin
+
+    >>> provideSubscriptionAdapter(ContainerTraverserPlugin,
+    ...                            (IMyContainer, IPublisherRequest),
+    ...                            ITraverserPlugin)
+
+  * the ``foo`` attribute. Luckily we also have a predeveloped traverser for
+    this:
+
+    >>> from z3c.traverser.traverser import \
+    ...     SingleAttributeTraverserPlugin
+    >>> provideSubscriptionAdapter(SingleAttributeTraverserPlugin('foo'),
+    ...                            (IMyContainer, IPublisherRequest))
+
+We can now use the pluggable traverser
+
+    >>> traverser = PluggableTraverser(myContainer, request)
+
+to look up items
+
+    >>> traverser.publishTraverse(request, 'blah')
+    123
+
+and the ``foo`` attribute:
+
+    >>> traverser.publishTraverse(request, 'foo')
+    True
+
+However, we cannot lookup the ``bar`` attribute or any other non-existent
+item:
+
+    >>> traverser.publishTraverse(request, 'bar')
+    Traceback (most recent call last):
+    ...
+    NotFound: Object: <MyContainer object at ...>, name: 'bar'
+
+    >>> traverser.publishTraverse(request, 'bad')
+    Traceback (most recent call last):
+    ...
+    NotFound: Object: <MyContainer object at ...>, name: 'bad'
+
+You can also add traversers that return an adapted object. For example, let's
+take the following adapter:
+
+    >>> class ISomeAdapter(Interface):
+    ...     pass
+
+    >>> from zope.component import adapts
+    >>> class SomeAdapter(object):
+    ...     implements(ISomeAdapter)
+    ...     adapts(IMyContainer)
+    ...
+    ...     def __init__(self, context):
+    ...         pass
+
+    >>> from zope.component import adapts, provideAdapter
+    >>> provideAdapter(SomeAdapter)
+
+Now we register this adapter under the traversal name ``some``:
+
+    >>> from z3c.traverser.traverser import AdapterTraverserPlugin
+    >>> provideSubscriptionAdapter(
+    ...     AdapterTraverserPlugin('some', ISomeAdapter),
+    ...     (IMyContainer, IPublisherRequest))
+
+So here is the result:
+
+    >>> traverser.publishTraverse(request, 'some')
+    <SomeAdapter object at ...>
+
+If the object is not adaptable, we'll get NotFound. Let's register a
+plugin that tries to query a named adapter for ISomeAdapter. The third
+argument for AdapterTraverserPlugin is used to specify the adapter name.
+
+    >>> provideSubscriptionAdapter(
+    ...     AdapterTraverserPlugin('badadapter', ISomeAdapter, 'other'),
+    ...     (IMyContainer, IPublisherRequest))
+
+    >>> traverser.publishTraverse(request, 'badadapter')
+    Traceback (most recent call last):
+    ...
+    NotFound: Object: <MyContainer object at ...>, name: 'badadapter'
+
+Traverser Plugins
+-----------------
+
+The `traverser` package comes with several default traverser plugins; three of
+them were already introduced above: `SingleAttributeTraverserPlugin`,
+`AdapterTraverserPlugin`, and `ContainerTraverserPlugin`. Another plugin is
+the the `NullTraverserPlugin`, which always just returns the object itself:
+
+    >>> from z3c.traverser.traverser import NullTraverserPlugin
+    >>> SomethingPlugin = NullTraverserPlugin('something')
+
+    >>> plugin = SomethingPlugin(content, request)
+    >>> plugin.publishTraverse(request, 'something')
+    <Content object at ...>
+
+    >>> plugin.publishTraverse(request, 'something else')
+    Traceback (most recent call last):
+    ...
+    NotFound: Object: <Content object at ...>, name: 'something else'
+
+All of the above traversers with exception of the `ContainerTraverserPlugin`
+are implementation of the abstract `NameTraverserPlugin` class. Name traversers
+are traversers that can resolve one particular name. By using the abstract
+`NameTraverserPlugin` class, all of the traverser boilerplate can be
+avoided. Here is a simple example that always returns a specific value for a
+traversed name:
+
+    >>> from z3c.traverser.traverser import NameTraverserPlugin
+    >>> class TrueTraverserPlugin(NameTraverserPlugin):
+    ...     traversalName = 'true'
+    ...     def _traverse(self, request, name):
+    ...         return True
+
+As you can see realized name traversers must implement the ``_traverse()``
+method, which is only responsible for returning the result. Of course it can
+also raise the `NotFound` error if something goes wrong during the
+computation. LEt's check it out:
+
+    >>> plugin = TrueTraverserPlugin(content, request)
+    >>> plugin.publishTraverse(request, 'true')
+    True
+
+    >>> plugin.publishTraverse(request, 'false')
+    Traceback (most recent call last):
+    ...
+    NotFound: Object: <Content object at ...>, name: 'false'
+
+A final traverser that is offered by the package is the
+`AttributeTraverserPlugin``, which simply allows one to traverse all
+accessible attributes of an object:
+
+    >>> from z3c.traverser.traverser import AttributeTraverserPlugin
+
+    >>> plugin = AttributeTraverserPlugin(myContainer, request)
+    >>> plugin.publishTraverse(request, 'foo')
+    True
+    >>> plugin.publishTraverse(request, 'bar')
+    False
+    >>> plugin.publishTraverse(request, 'blah')
+    Traceback (most recent call last):
+    ...
+    NotFound: Object: <MyContainer object at ...>, name: 'blah'
+    >>> plugin.publishTraverse(request, 'some')
+    Traceback (most recent call last):
+    ...
+    NotFound: Object: <MyContainer object at ...>, name: 'some'
+
+
+Browser traverser
+-----------------
+
+There's also a special subclass of the PluggableTraverser that 
+implements the ``IBrowserPublisher`` interface, thus providing the
+``browserDefault`` method that returns a default object and a view
+name to traverse and use if there's no more steps to traverse.
+
+Let's provide a view name registered as an IDefaultView adapter. This
+is usually done by zope.app.publisher's browser:defaultView directive. 
+
+    >>> from zope.component.interfaces import IDefaultViewName
+    >>> provideAdapter('view.html', (IContent, Interface), IDefaultViewName)
+
+    >>> from z3c.traverser.browser import PluggableBrowserTraverser
+    >>> traverser = PluggableBrowserTraverser(content, request)
+    >>> traverser.browserDefault(request)
+    (<Content object at 0x...>, ('@@view.html',))

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/browser.py
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/browser.py	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/browser.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,29 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Pluggable Browser Traverser
-
-$Id$
-"""
-__docformat__ = "reStructuredText"
-from zope.app import zapi
-from z3c.traverser.traverser import PluggableTraverser
-
-
-class PluggableBrowserTraverser(PluggableTraverser):
-
-    def browserDefault(self, request):
-        """See zope.publisher.browser.interfaces.IBrowserPublisher"""
-        view_name = zapi.getDefaultViewName(self.context, request)
-        view_uri = "@@%s" %view_name
-        return self.context, (view_uri,)

Copied: z3c.traverser/tags/0.2.4/src/z3c/traverser/browser.py (from rev 95978, z3c.traverser/trunk/src/z3c/traverser/browser.py)
===================================================================
--- z3c.traverser/tags/0.2.4/src/z3c/traverser/browser.py	                        (rev 0)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/browser.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -0,0 +1,43 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Pluggable Browser Traverser
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+from zope.component import getSiteManager
+from zope.component.interfaces import ComponentLookupError, IDefaultViewName
+from zope.interface import implements, providedBy
+from zope.publisher.interfaces.browser import IBrowserPublisher
+
+from z3c.traverser.traverser import PluggableTraverser
+
+# copy the function from zope.app.publisher not to depend on it
+def getDefaultViewName(object, request):
+    name = getSiteManager().adapters.lookup(
+        (providedBy(object), providedBy(request)), IDefaultViewName)
+    if name is not None:
+        return name
+    raise ComponentLookupError("Couldn't find default view name",
+                               object, request)
+
+class PluggableBrowserTraverser(PluggableTraverser):
+
+    implements(IBrowserPublisher)
+
+    def browserDefault(self, request):
+        """See zope.publisher.browser.interfaces.IBrowserPublisher"""
+        view_name = getDefaultViewName(self.context, request)
+        view_uri = "@@%s" % view_name
+        return self.context, (view_uri,)

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/README.txt
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/stackinfo/README.txt	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/README.txt	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,255 +0,0 @@
-===============================================
-Extracting Information from the Traversal Stack
-===============================================
-
-This package allows to define virtual traversal paths for collecting
-arbitrary information from the traversal stack instead of, for
-example, query strings.
-
-In contrast to the common way of defining custom Traversers, this
-implementation does not require to go through the whole traversal
-process step by step. The traversal information needed is taken from
-the traversalstack directly and the used parts of the stack are
-consumed. This way one don't have to define proxy classes just for
-traversal.
-
-This implementation does not work in tales because it requires the
-traversalstack of the request.
-
-For each name in the traversal stack a named multiadapter is looked up
-for ITraversalStackConsumer, if found the item gets removed from the
-stack and the adapter is added to the request annotation.
-
-  >>> from z3c.traverser.stackinfo import traversing
-  >>> from z3c.traverser.stackinfo import interfaces
-
-If there are no adapters defined, the traversalstack is kept as is. To
-show this behaviour we define some sample classes.
-
-  >>> from zope import interface
-  >>> class IContent(interface.Interface):
-  ...     pass
-
-  >>> from zope.app.folder.folder import Folder
-  >>> class Content(Folder):
-  ...     interface.implements(IContent)
-
-There is a convinience function which returns an iterator which
-iterates over tuples of adapterName, adapter. Additionally the
-traversal stack of the request is consumed if needed.
-
-  >>> from zope.publisher.browser import TestRequest
-  >>> from zope.publisher.interfaces.browser import IBrowserRequest
-  >>> request = TestRequest()
-
-We set the traversal stack manually for testing here.
-
-  >>> request.setTraversalStack([u'index.html', u'path', u'some'])
-  >>> content = Content()
-
-So if no ITraversalStackConsumer adapters are found the stack is left
-untouched.
-
-  >>> list(traversing.getStackConsumers(content, request))
-  []
-  >>> request.getTraversalStack()
-  [u'index.html', u'path', u'some']
-
-There is a base class for consumer implementations which implements
-the ITraversalStackConsumer interface.
-
-  >>> from z3c.traverser.stackinfo import consumer
-  >>> from zope.interface.verify import verifyObject
-  >>> o = consumer.BaseConsumer(None, None)
-  >>> verifyObject(interfaces.ITraversalStackConsumer,o)
-  True
-
-Let us define a custom consumer.
-
-  >>> from zope import component
-  >>> class DummyConsumer(consumer.BaseConsumer):
-  ...     component.adapts(IContent, IBrowserRequest)
-  >>> component.provideAdapter(DummyConsumer, name='some')
-
-Now we will find the newly registered consumer and the 'some' part of
-the stack is consumed.
-
-  >>> consumers = list(traversing.getStackConsumers(content, request))
-  >>> consumers
-  [(u'some', <DummyConsumer named u'some'>)]
-  >>> request.getTraversalStack()
-  [u'index.html', u'path']
-
-Each consumer at least has to consume one element, which is always
-the name under which the adapter was registered under.
-
-  >>> name, cons = consumers[0]
-  >>> cons.__name__
-  u'some'
-
-Let us provide another adapter, to demonstrate that the adpaters
-always have the reverse order of the traversal stack. This is actually
-the order in the url.
-
-  >>> component.provideAdapter(DummyConsumer, name='other')
-  >>> stack = [u'index.html', u'path', u'some', u'other']
-  >>> request.setTraversalStack(stack)
-  >>> consumers = list(traversing.getStackConsumers(content, request))
-  >>> consumers
-  [(u'other', <DummyConsumer named u'other'>),
-   (u'some', <DummyConsumer named u'some'>)]
-
-  >>> [c.__name__ for name, c in consumers]
-  [u'other', u'some']
-
-The arguments attribute of the consumer class defines how many
-arguments are consumed/needed from the stack. Let us create a KeyValue
-consumer, that should extract key value pairs from the stack.
-
-  >>> class KeyValueConsumer(DummyConsumer):
-  ...     arguments=('key', 'value')
-  >>> component.provideAdapter(KeyValueConsumer, name='kv')
-  >>> stack = [u'index.html', u'value', u'key', u'kv']
-  >>> request.setTraversalStack(stack)
-  >>> consumers = list(traversing.getStackConsumers(content, request))
-  >>> consumers
-  [(u'kv', <KeyValueConsumer named u'kv'>)]
-  >>> request.getTraversalStack()
-  [u'index.html']
-  >>> name, cons = consumers[0]
-  >>> cons.key
-  u'key'
-  >>> cons.value
-  u'value'
-
-We can of course use multiple consumers of the same type.
-
-  >>> stack = [u'index.html', u'v2', u'k2', u'kv', u'v1', u'k1', u'kv']
-  >>> request.setTraversalStack(stack)
-  >>> consumers = list(traversing.getStackConsumers(content, request))
-  >>> [(c.__name__, c.key, c.value) for name, c in consumers]
-  [(u'kv', u'k1', u'v1'), (u'kv', u'k2', u'v2')]
-
-If we have too less arguments a NotFound exception.
-
-  >>> stack = [u'k2', u'kv', u'v1', u'k1', u'kv']
-  >>> request.setTraversalStack(stack)
-  >>> consumers = list(traversing.getStackConsumers(content, request))
-  Traceback (most recent call last):
-    ...
-  NotFound: Object: <Content object at ...>, name: u'kv'
-
-
-In order to actually use the stack consumers to retrieve information,
-there is another convinience function which stores the consumers in
-the requests annotations. This should noramlly be called on
-BeforeTraverseEvents.
-
-  >>> stack = [u'index.html', u'v2', u'k2', u'kv', u'v1', u'k1', u'kv']
-  >>> request.setTraversalStack(stack)
-  >>> traversing.applyStackConsumers(content, request)
-  >>> request.annotations[traversing.CONSUMERS_ANNOTATION_KEY]
-  [<KeyValueConsumer named u'kv'>,
-   <KeyValueConsumer named u'kv'>]
-
-Instead of messing with the annotations one just can adapt the request
-to ITraversalStackInfo.
-
-  >>> component.provideAdapter(consumer.requestTraversalStackInfo)
-  >>> ti = interfaces.ITraversalStackInfo(request)
-  >>> ti
-  (<KeyValueConsumer named u'kv'>, <KeyValueConsumer named u'kv'>)
-
-  >>> len(ti)
-  2
-
-The adapter always returs an empty TraversalStackInfoObject if there
-is no traversalstack information.
-
-  >>> request = TestRequest()
-  >>> ti = interfaces.ITraversalStackInfo(request)
-  >>> len(ti)
-  0
-
-
-Virtual Host
-------------
-
-If virtual hosts are used the traversal stack contains aditional information
-for the virtual host which will interfere which the stack consumer.
-
-  >>> stack = [u'index.html', u'value', u'key',
-  ...          u'kv', u'++', u'inside vh', '++vh++something']
-  >>> request.setTraversalStack(stack)
-  >>> consumers = list(traversing.getStackConsumers(content, request))
-  >>> consumers
-  [(u'kv', <KeyValueConsumer named u'kv'>)]
-  >>> request.getTraversalStack()
-  [u'index.html', u'++', u'inside vh', '++vh++something']
-
-
-URL Handling
-------------
-
-Let us try these things with a real url, in our test the root is the site.
-
-  >>> from zope.traversing.browser.absoluteurl import absoluteURL
-  >>> absoluteURL(root, request)
-  'http://127.0.0.1'
-
-There is an unconsumedURL function which returns the url of an object
-with the traversal information, which is normally omitted.
-
-  >>> request = TestRequest()
-  >>> root['content'] = content
-  >>> absoluteURL(root['content'], request)
-  'http://127.0.0.1/content'
-  >>> stack = [u'index.html', u'v2 space', u'k2', u'kv', u'v1', u'k1', u'kv']
-  >>> request.setTraversalStack(stack)
-  >>> traversing.applyStackConsumers(root['content'], request)
-  >>> traversing.unconsumedURL(root['content'], request)
-  'http://127.0.0.1/content/kv/k1/v1/kv/k2/v2%20space'
-
-Let us have more than one content object
-
-  >>> under = content[u'under'] = Content()
-  >>> request = TestRequest()
-  >>> traversing.unconsumedURL(under, request)
-  'http://127.0.0.1/content/under'
-
-We add some consumers to the above object
-
-  >>> request = TestRequest()
-  >>> stack = [u'index.html', u'value1', u'key1', u'kv']
-  >>> request.setTraversalStack(stack)
-  >>> traversing.applyStackConsumers(root['content'], request)
-  >>> traversing.unconsumedURL(root['content'], request)
-  'http://127.0.0.1/content/kv/key1/value1'
-  >>> traversing.unconsumedURL(under, request)
-  'http://127.0.0.1/content/kv/key1/value1/under'
-
-And now to the object below too.
-
-  >>> request = TestRequest()
-  >>> stack = [u'index.html', u'value1', u'key1', u'kv']
-  >>> request.setTraversalStack(stack)
-  >>> traversing.applyStackConsumers(root['content'], request)
-  >>> stack = [u'index.html', u'value2', u'key2', u'kv']
-  >>> request.setTraversalStack(stack)
-  >>> traversing.applyStackConsumers(under, request)
-  >>> traversing.unconsumedURL(root['content'], request)
-  'http://127.0.0.1/content/kv/key1/value1'
-  >>> traversing.unconsumedURL(under, request)
-  'http://127.0.0.1/content/kv/key1/value1/under/kv/key2/value2'
-
-Or only the object below.
-
-  >>> request = TestRequest()
-  >>> traversing.applyStackConsumers(root['content'], request)
-  >>> stack = [u'index.html', u'value2', u'key2', u'kv']
-  >>> request.setTraversalStack(stack)
-  >>> traversing.applyStackConsumers(under, request)
-  >>> traversing.unconsumedURL(root['content'], request)
-  'http://127.0.0.1/content'
-  >>> traversing.unconsumedURL(under, request)
-  'http://127.0.0.1/content/under/kv/key2/value2'

Copied: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/README.txt (from rev 95978, z3c.traverser/trunk/src/z3c/traverser/stackinfo/README.txt)
===================================================================
--- z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/README.txt	                        (rev 0)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/README.txt	2009-02-02 15:44:41 UTC (rev 95984)
@@ -0,0 +1,270 @@
+===============================================
+Extracting Information from the Traversal Stack
+===============================================
+
+This package allows to define virtual traversal paths for collecting
+arbitrary information from the traversal stack instead of, for
+example, query strings.
+
+In contrast to the common way of defining custom Traversers, this
+implementation does not require to go through the whole traversal
+process step by step. The traversal information needed is taken from
+the traversalstack directly and the used parts of the stack are
+consumed. This way one don't have to define proxy classes just for
+traversal.
+
+This implementation does not work in tales because it requires the
+traversalstack of the request.
+
+For each name in the traversal stack a named multiadapter is looked up
+for ITraversalStackConsumer, if found the item gets removed from the
+stack and the adapter is added to the request annotation.
+
+  >>> from z3c.traverser.stackinfo import traversing
+  >>> from z3c.traverser.stackinfo import interfaces
+
+If there are no adapters defined, the traversalstack is kept as is. To
+show this behaviour we define some sample classes.
+
+  >>> from zope import interface
+  >>> class IContent(interface.Interface):
+  ...     pass
+
+  >>> from zope.app.folder.folder import Folder
+  >>> class Content(Folder):
+  ...     interface.implements(IContent)
+
+There is a convinience function which returns an iterator which
+iterates over tuples of adapterName, adapter. Additionally the
+traversal stack of the request is consumed if needed.
+
+  >>> from zope.publisher.browser import TestRequest
+  >>> from zope.publisher.interfaces.browser import IBrowserRequest
+  >>> request = TestRequest()
+
+We set the traversal stack manually for testing here.
+
+  >>> request.setTraversalStack([u'index.html', u'path', u'some'])
+  >>> content = Content()
+
+So if no ITraversalStackConsumer adapters are found the stack is left
+untouched.
+
+  >>> list(traversing.getStackConsumers(content, request))
+  []
+  >>> request.getTraversalStack()
+  [u'index.html', u'path', u'some']
+
+There is a base class for consumer implementations which implements
+the ITraversalStackConsumer interface.
+
+  >>> from z3c.traverser.stackinfo import consumer
+  >>> from zope.interface.verify import verifyObject
+  >>> o = consumer.BaseConsumer(None, None)
+  >>> verifyObject(interfaces.ITraversalStackConsumer,o)
+  True
+
+Let us define a custom consumer.
+
+  >>> from zope import component
+  >>> class DummyConsumer(consumer.BaseConsumer):
+  ...     component.adapts(IContent, IBrowserRequest)
+  >>> component.provideAdapter(DummyConsumer, name='some')
+
+Now we will find the newly registered consumer and the 'some' part of
+the stack is consumed.
+
+  >>> consumers = list(traversing.getStackConsumers(content, request))
+  >>> consumers
+  [(u'some', <DummyConsumer named u'some'>)]
+  >>> request.getTraversalStack()
+  [u'index.html', u'path']
+
+Each consumer at least has to consume one element, which is always
+the name under which the adapter was registered under.
+
+  >>> name, cons = consumers[0]
+  >>> cons.__name__
+  u'some'
+
+Let us provide another adapter, to demonstrate that the adpaters
+always have the reverse order of the traversal stack. This is actually
+the order in the url.
+
+  >>> component.provideAdapter(DummyConsumer, name='other')
+  >>> stack = [u'index.html', u'path', u'some', u'other']
+  >>> request.setTraversalStack(stack)
+  >>> consumers = list(traversing.getStackConsumers(content, request))
+  >>> consumers
+  [(u'other', <DummyConsumer named u'other'>),
+   (u'some', <DummyConsumer named u'some'>)]
+
+  >>> [c.__name__ for name, c in consumers]
+  [u'other', u'some']
+
+The arguments attribute of the consumer class defines how many
+arguments are consumed/needed from the stack. Let us create a KeyValue
+consumer, that should extract key value pairs from the stack.
+
+  >>> class KeyValueConsumer(DummyConsumer):
+  ...     arguments=('key', 'value')
+  >>> component.provideAdapter(KeyValueConsumer, name='kv')
+  >>> stack = [u'index.html', u'value', u'key', u'kv']
+  >>> request.setTraversalStack(stack)
+  >>> consumers = list(traversing.getStackConsumers(content, request))
+  >>> consumers
+  [(u'kv', <KeyValueConsumer named u'kv'>)]
+  >>> request.getTraversalStack()
+  [u'index.html']
+  >>> name, cons = consumers[0]
+  >>> cons.key
+  u'key'
+  >>> cons.value
+  u'value'
+
+We can of course use multiple consumers of the same type.
+
+  >>> stack = [u'index.html', u'v2', u'k2', u'kv', u'v1', u'k1', u'kv']
+  >>> request.setTraversalStack(stack)
+  >>> consumers = list(traversing.getStackConsumers(content, request))
+  >>> [(c.__name__, c.key, c.value) for name, c in consumers]
+  [(u'kv', u'k1', u'v1'), (u'kv', u'k2', u'v2')]
+
+If we have too less arguments a NotFound exception.
+
+  >>> stack = [u'k2', u'kv', u'v1', u'k1', u'kv']
+  >>> request.setTraversalStack(stack)
+  >>> consumers = list(traversing.getStackConsumers(content, request))
+  Traceback (most recent call last):
+    ...
+  NotFound: Object: <Content object at ...>, name: u'kv'
+
+
+In order to actually use the stack consumers to retrieve information,
+there is another convinience function which stores the consumers in
+the requests annotations. This should noramlly be called on
+BeforeTraverseEvents.
+
+  >>> stack = [u'index.html', u'v2', u'k2', u'kv', u'v1', u'k1', u'kv']
+  >>> request.setTraversalStack(stack)
+  >>> traversing.applyStackConsumers(content, request)
+  >>> request.annotations[traversing.CONSUMERS_ANNOTATION_KEY]
+  [<KeyValueConsumer named u'kv'>,
+   <KeyValueConsumer named u'kv'>]
+
+Instead of messing with the annotations one just can adapt the request
+to ITraversalStackInfo.
+
+  >>> component.provideAdapter(consumer.requestTraversalStackInfo)
+  >>> ti = interfaces.ITraversalStackInfo(request)
+  >>> ti
+  (<KeyValueConsumer named u'kv'>, <KeyValueConsumer named u'kv'>)
+
+  >>> len(ti)
+  2
+
+The adapter always returs an empty TraversalStackInfoObject if there
+is no traversalstack information.
+
+  >>> request = TestRequest()
+  >>> ti = interfaces.ITraversalStackInfo(request)
+  >>> len(ti)
+  0
+
+
+Virtual Host
+------------
+
+If virtual hosts are used the traversal stack contains aditional information
+for the virtual host which will interfere which the stack consumer.
+
+  >>> stack = [u'index.html', u'value', u'key',
+  ...          u'kv', u'++', u'inside vh', '++vh++something']
+  >>> request.setTraversalStack(stack)
+  >>> consumers = list(traversing.getStackConsumers(content, request))
+  >>> consumers
+  [(u'kv', <KeyValueConsumer named u'kv'>)]
+  >>> request.getTraversalStack()
+  [u'index.html', u'++', u'inside vh', '++vh++something']
+
+
+URL Handling
+------------
+
+Let us try these things with a real url, in our test the root is the site.
+
+  >>> from zope.traversing.browser.absoluteurl import absoluteURL
+  >>> absoluteURL(root, request)
+  'http://127.0.0.1'
+
+There is an unconsumedURL function which returns the url of an object
+with the traversal information, which is normally omitted.
+
+  >>> request = TestRequest()
+  >>> root['content'] = content
+  >>> absoluteURL(root['content'], request)
+  'http://127.0.0.1/content'
+  >>> stack = [u'index.html', u'v2 space', u'k2', u'kv', u'v1', u'k1', u'kv']
+  >>> request.setTraversalStack(stack)
+  >>> traversing.applyStackConsumers(root['content'], request)
+  >>> traversing.unconsumedURL(root['content'], request)
+  'http://127.0.0.1/content/kv/k1/v1/kv/k2/v2%20space'
+
+Let us have more than one content object
+
+  >>> under = content[u'under'] = Content()
+  >>> request = TestRequest()
+  >>> traversing.unconsumedURL(under, request)
+  'http://127.0.0.1/content/under'
+
+We add some consumers to the above object
+
+  >>> request = TestRequest()
+  >>> stack = [u'index.html', u'value1', u'key1', u'kv']
+  >>> request.setTraversalStack(stack)
+  >>> traversing.applyStackConsumers(root['content'], request)
+  >>> traversing.unconsumedURL(root['content'], request)
+  'http://127.0.0.1/content/kv/key1/value1'
+  >>> traversing.unconsumedURL(under, request)
+  'http://127.0.0.1/content/kv/key1/value1/under'
+
+And now to the object below too.
+
+  >>> request = TestRequest()
+  >>> stack = [u'index.html', u'value1', u'key1', u'kv']
+  >>> request.setTraversalStack(stack)
+  >>> traversing.applyStackConsumers(root['content'], request)
+  >>> stack = [u'index.html', u'value2', u'key2', u'kv']
+  >>> request.setTraversalStack(stack)
+  >>> traversing.applyStackConsumers(under, request)
+  >>> traversing.unconsumedURL(root['content'], request)
+  'http://127.0.0.1/content/kv/key1/value1'
+  >>> traversing.unconsumedURL(under, request)
+  'http://127.0.0.1/content/kv/key1/value1/under/kv/key2/value2'
+
+Or only the object below.
+
+  >>> request = TestRequest()
+  >>> traversing.applyStackConsumers(root['content'], request)
+  >>> stack = [u'index.html', u'value2', u'key2', u'kv']
+  >>> request.setTraversalStack(stack)
+  >>> traversing.applyStackConsumers(under, request)
+  >>> traversing.unconsumedURL(root['content'], request)
+  'http://127.0.0.1/content'
+  >>> traversing.unconsumedURL(under, request)
+  'http://127.0.0.1/content/under/kv/key2/value2'
+
+The unconsumedURL function is also available as a view, named
+``unconsumed_url``, similar to ``absolute_url`` one.
+
+  >>> from zope.component import getMultiAdapter
+  >>> url = getMultiAdapter((under, request), name='unconsumed_url')
+
+  >>> str(url)
+  'http://127.0.0.1/content/under/kv/key2/value2'
+
+  >>> unicode(url)
+  u'http://127.0.0.1/content/under/kv/key2/value2'
+
+  >>> url()
+  'http://127.0.0.1/content/under/kv/key2/value2'

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/SETUP.cfg
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/stackinfo/SETUP.cfg	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/SETUP.cfg	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,3 +0,0 @@
-<data-files zopeskel/etc/package-includes>
-    z3c.traverser.stackinfo-*.zcml
-</data-files>
\ No newline at end of file

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/consumer.py
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/stackinfo/consumer.py	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/consumer.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,40 +0,0 @@
-from zope import interface, component
-import interfaces
-import traversing
-from zope.publisher.interfaces.browser import IBrowserRequest
-
- at component.adapter(IBrowserRequest)
- at interface.implementer(interfaces.ITraversalStackInfo)
-def requestTraversalStackInfo(request):
-    cons = request.annotations.get(traversing.CONSUMERS_ANNOTATION_KEY, [])
-    return TraversalStackInfo(cons)
-
-class TraversalStackInfo(tuple):
-    interface.implements(interfaces.ITraversalStackInfo)
-
-class BaseConsumer(object):
-    interface.implements(interfaces.ITraversalStackConsumer)
-
-    arguments = ()
-    __name__ = None
-
-    def __init__(self, context, request):
-        self.context=context
-        self.request=request
-
-    def consume(self):
-        stack = self.request.getTraversalStack()
-        self.__name__ = stack.pop()
-        consumed = [self.__name__]
-        for name in self.arguments:
-            v = stack.pop()
-            consumed.append(v)
-            setattr(self, name, v)
-        self.request.setTraversalStack(stack)
-        return consumed
-
-    def __repr__(self):
-        return '<%s named %r>' % (self.__class__.__name__,
-                                  self.__name__)
-
-

Copied: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/consumer.py (from rev 95983, z3c.traverser/trunk/src/z3c/traverser/stackinfo/consumer.py)
===================================================================
--- z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/consumer.py	                        (rev 0)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/consumer.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -0,0 +1,41 @@
+from zope import interface, component
+from zope.publisher.interfaces.browser import IBrowserRequest
+
+import interfaces
+import traversing
+
+ at component.adapter(IBrowserRequest)
+ at interface.implementer(interfaces.ITraversalStackInfo)
+def requestTraversalStackInfo(request):
+    cons = request.annotations.get(traversing.CONSUMERS_ANNOTATION_KEY, [])
+    return TraversalStackInfo(cons)
+
+class TraversalStackInfo(tuple):
+    interface.implements(interfaces.ITraversalStackInfo)
+
+class BaseConsumer(object):
+    interface.implements(interfaces.ITraversalStackConsumer)
+
+    arguments = ()
+    __name__ = None
+
+    def __init__(self, context, request):
+        self.context=context
+        self.request=request
+
+    def consume(self):
+        stack = self.request.getTraversalStack()
+        self.__name__ = stack.pop()
+        consumed = [self.__name__]
+        for name in self.arguments:
+            v = stack.pop()
+            consumed.append(v)
+            setattr(self, name, v)
+        self.request.setTraversalStack(stack)
+        return consumed
+
+    def __repr__(self):
+        return '<%s named %r>' % (self.__class__.__name__,
+                                  self.__name__)
+
+

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/ftesting.zcml
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/stackinfo/ftesting.zcml	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/ftesting.zcml	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,68 +0,0 @@
-<configure xmlns="http://namespaces.zope.org/zope"
-           xmlns:browser="http://namespaces.zope.org/browser"
-           xmlns:zcml="http://namespaces.zope.org/zcml"
-           i18n_domain="zope">
-
-  <include
-      zcml:condition="installed zope.app.zcmlfiles"
-      package="zope.app.zcmlfiles"
-      />
-  <include
-      zcml:condition="not-installed zope.app.zcmlfiles"
-      package="zope.app"
-      />
-
-  <include package="zope.app.securitypolicy" file="meta.zcml" />
-
-  <include package="zope.app.authentication" />
-
-  <securityPolicy
-    component="zope.securitypolicy.zopepolicy.ZopeSecurityPolicy" />
-
-  <include package="zope.app.securitypolicy" />
-  <include package="zope.app.session" />
-
-  <include package="z3c.traverser.stackinfo"/>
-  <include package="z3c.traverser.stackinfo.testing"/>
-
-  <role id="zope.Anonymous" title="Everybody"
-        description="All users have this role implicitly" />
-  <role id="zope.Manager" title="Site Manager" />
-  <grantAll role="zope.Manager" />
-  <principal
-   id="zope.manager"
-   title="Administrator"
-   login="mgr"
-   password="mgrpw" />
-  <grant
-   role="zope.Manager"
-   principal="zope.manager"
-   />
-
-  <unauthenticatedPrincipal
-    id="zope.anybody"
-    title="Unauthenticated User" />
-
-  <unauthenticatedGroup
-    id="zope.Anybody"
-    title="Unauthenticated Users"
-    />
-
-  <authenticatedGroup
-    id="zope.Authenticated"
-    title="Authenticated Users"
-    />
-
-  <everybodyGroup
-    id="zope.Everybody"
-    title="All Users"
-    />
-
-  <grant permission="zope.View"
-         role="zope.Anonymous" />
-  <grant permission="zope.app.dublincore.view"
-         role="zope.Anonymous" />
-
-
-
-</configure>

Copied: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/ftesting.zcml (from rev 95978, z3c.traverser/trunk/src/z3c/traverser/stackinfo/ftesting.zcml)
===================================================================
--- z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/ftesting.zcml	                        (rev 0)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/ftesting.zcml	2009-02-02 15:44:41 UTC (rev 95984)
@@ -0,0 +1,68 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:browser="http://namespaces.zope.org/browser"
+           xmlns:zcml="http://namespaces.zope.org/zcml"
+           i18n_domain="zope">
+
+  <include
+      zcml:condition="installed zope.app.zcmlfiles"
+      package="zope.app.zcmlfiles"
+      />
+  <include
+      zcml:condition="not-installed zope.app.zcmlfiles"
+      package="zope.app"
+      />
+
+  <include package="zope.app.securitypolicy" file="meta.zcml" />
+
+  <include package="zope.app.authentication" />
+
+  <securityPolicy
+    component="zope.securitypolicy.zopepolicy.ZopeSecurityPolicy" />
+
+  <include package="zope.app.securitypolicy" />
+  <include package="zope.session" />
+
+  <include package="z3c.traverser.stackinfo"/>
+  <include package="z3c.traverser.stackinfo.testing"/>
+
+  <role id="zope.Anonymous" title="Everybody"
+        description="All users have this role implicitly" />
+  <role id="zope.Manager" title="Site Manager" />
+  <grantAll role="zope.Manager" />
+  <principal
+   id="zope.manager"
+   title="Administrator"
+   login="mgr"
+   password="mgrpw" />
+  <grant
+   role="zope.Manager"
+   principal="zope.manager"
+   />
+
+  <unauthenticatedPrincipal
+    id="zope.anybody"
+    title="Unauthenticated User" />
+
+  <unauthenticatedGroup
+    id="zope.Anybody"
+    title="Unauthenticated Users"
+    />
+
+  <authenticatedGroup
+    id="zope.Authenticated"
+    title="Authenticated Users"
+    />
+
+  <everybodyGroup
+    id="zope.Everybody"
+    title="All Users"
+    />
+
+  <grant permission="zope.View"
+         role="zope.Anonymous" />
+  <grant permission="zope.app.dublincore.view"
+         role="zope.Anonymous" />
+
+
+
+</configure>

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/configure.zcml
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/stackinfo/testing/configure.zcml	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/configure.zcml	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,21 +0,0 @@
-<configure xmlns="http://namespaces.zope.org/zope"
-           xmlns:browser="http://namespaces.zope.org/browser"
-           xmlns:i18n="http://namespaces.zope.org/i18n"
-           i18n_domain="zope">
-
- <browser:page
-  for="zope.app.component.interfaces.ISite"
-  name="stackinfo.html"
-  permission="zope.Public"
-  class=".views.StackInfoView"/>
-
- <subscriber
-  for="zope.app.component.interfaces.ISite
-       zope.app.publication.interfaces.IBeforeTraverseEvent"
-  handler="z3c.traverser.stackinfo.applyStackConsumersHandler"
-  />
-
- <adapter factory=".consumer.KeyValueConsumer"
-          name="kv"/>
-
- </configure>
\ No newline at end of file

Copied: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/configure.zcml (from rev 95978, z3c.traverser/trunk/src/z3c/traverser/stackinfo/testing/configure.zcml)
===================================================================
--- z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/configure.zcml	                        (rev 0)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/configure.zcml	2009-02-02 15:44:41 UTC (rev 95984)
@@ -0,0 +1,21 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:browser="http://namespaces.zope.org/browser"
+           xmlns:i18n="http://namespaces.zope.org/i18n"
+           i18n_domain="zope">
+
+ <browser:page
+  for="zope.location.interfaces.ISite"
+  name="stackinfo.html"
+  permission="zope.Public"
+  class=".views.StackInfoView"/>
+
+ <subscriber
+  for="zope.location.interfaces.ISite
+       zope.app.publication.interfaces.IBeforeTraverseEvent"
+  handler="z3c.traverser.stackinfo.applyStackConsumersHandler"
+  />
+
+ <adapter factory=".consumer.KeyValueConsumer"
+          name="kv"/>
+
+ </configure>
\ No newline at end of file

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/consumer.py
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/stackinfo/testing/consumer.py	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/consumer.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,11 +0,0 @@
-from z3c.traverser.stackinfo.consumer import BaseConsumer
-from z3c.traverser.stackinfo import interfaces
-from zope import interface, component
-from zope.app.component.interfaces import ISite
-from zope.publisher.interfaces.browser import IBrowserRequest
-
-class KeyValueConsumer(BaseConsumer):
-    interface.implements(interfaces.ITraversalStackConsumer)
-    component.adapts(ISite, IBrowserRequest)
-    arguments=('key', 'value')
-    

Copied: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/consumer.py (from rev 95983, z3c.traverser/trunk/src/z3c/traverser/stackinfo/testing/consumer.py)
===================================================================
--- z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/consumer.py	                        (rev 0)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/consumer.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -0,0 +1,12 @@
+from zope import interface, component
+from zope.location.interfaces import ISite
+from zope.publisher.interfaces.browser import IBrowserRequest
+
+from z3c.traverser.stackinfo.consumer import BaseConsumer
+from z3c.traverser.stackinfo import interfaces
+
+class KeyValueConsumer(BaseConsumer):
+    interface.implements(interfaces.ITraversalStackConsumer)
+    component.adapts(ISite, IBrowserRequest)
+    arguments=('key', 'value')
+    

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/views.py
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/stackinfo/testing/views.py	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/views.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,16 +0,0 @@
-from z3c.traverser.stackinfo import interfaces
-from zope.traversing.browser.absoluteurl import absoluteURL
-
-class StackInfoView(object):
-
-    def __call__(self):
-        url = absoluteURL(self, self.request)
-        res = [u'Stack Info from object at %s:' % url]
-        for consumer in interfaces.ITraversalStackInfo(
-            self.request):
-            res.append(u'consumer %s:' % consumer.__name__)
-            for arg in consumer.arguments:
-                res.append(u'%s = %r' % (arg, getattr(consumer, arg)))
-        return u'\n'.join(res)
-                
-        

Copied: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/views.py (from rev 95983, z3c.traverser/trunk/src/z3c/traverser/stackinfo/testing/views.py)
===================================================================
--- z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/views.py	                        (rev 0)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/testing/views.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -0,0 +1,17 @@
+from zope.traversing.browser.absoluteurl import absoluteURL
+
+from z3c.traverser.stackinfo import interfaces
+
+class StackInfoView(object):
+
+    def __call__(self):
+        url = absoluteURL(self, self.request)
+        res = [u'Stack Info from object at %s:' % url]
+        for consumer in interfaces.ITraversalStackInfo(
+            self.request):
+            res.append(u'consumer %s:' % consumer.__name__)
+            for arg in consumer.arguments:
+                res.append(u'%s = %r' % (arg, getattr(consumer, arg)))
+        return u'\n'.join(res)
+                
+        

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/tests.py
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/stackinfo/tests.py	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/tests.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,26 +0,0 @@
-import doctest
-import unittest
-from zope.testing.doctestunit import DocFileSuite, DocFileSuite
-from zope.app.testing import setup
-import zope.traversing.testing
-
-def setUp(test):
-    root = setup.placefulSetUp(True)
-    zope.traversing.testing.setUp()
-    test.globs['root'] = root
-
-def tearDown(test):
-    setup.placefulTearDown()
-
-def test_suite():
-    
-    return unittest.TestSuite(
-        (
-        DocFileSuite('README.txt',
-                     setUp=setUp, tearDown=tearDown,
-                     optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
-                     ),
-        ))
-
-if __name__ == '__main__':
-    unittest.main(defaultTest='test_suite')

Copied: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/tests.py (from rev 95978, z3c.traverser/trunk/src/z3c/traverser/stackinfo/tests.py)
===================================================================
--- z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/tests.py	                        (rev 0)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/tests.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -0,0 +1,33 @@
+import doctest
+import unittest
+from zope.testing.doctestunit import DocFileSuite, DocFileSuite
+from zope.app.testing import setup
+from zope.component import provideAdapter
+from zope.interface import Interface
+from zope.publisher.interfaces.http import IHTTPRequest
+import zope.traversing.testing
+
+from z3c.traverser.stackinfo.traversing import UnconsumedURL
+
+def setUp(test):
+    root = setup.placefulSetUp(True)
+    zope.traversing.testing.setUp()
+    test.globs['root'] = root
+    provideAdapter(UnconsumedURL, (Interface, IHTTPRequest), Interface,
+                   name='unconsumed_url')
+
+def tearDown(test):
+    setup.placefulTearDown()
+
+def test_suite():
+    
+    return unittest.TestSuite(
+        (
+        DocFileSuite('README.txt',
+                     setUp=setUp, tearDown=tearDown,
+                     optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+                     ),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/traversing.py
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/stackinfo/traversing.py	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/traversing.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,132 +0,0 @@
-from zope import component
-import interfaces
-from zope.publisher.interfaces import NotFound
-from zope.traversing.browser.absoluteurl import absoluteURL
-import urllib
-from zope.publisher.browser import BrowserView
-
-CONSUMERS_ANNOTATION_KEY='z3c.traverser.consumers'
-CONSUMED_ANNOTATION_KEY='z3c.traverser.consumed'
-
-def getStackConsumers(context, request):
-    """consumes the stack"""
-    vhStack = VHStack(request)
-    while True:
-        vhStack.prepare()
-        stack = request.getTraversalStack()
-        if not stack:
-            break
-        name = stack[-1]
-        consumer = component.queryMultiAdapter(
-                        (context, request),
-                        interface=interfaces.ITraversalStackConsumer,
-                        name=name)
-        if consumer is None:
-            break
-        try:
-            consumer.consume()
-        except IndexError:
-            raise NotFound(context, name, request)
-        vhStack.reset()
-        yield (name, consumer)
-    vhStack.reset()
-
-
-def applyStackConsumers(context, request):
-    if not request.annotations.has_key(CONSUMED_ANNOTATION_KEY):
-        request.annotations[CONSUMED_ANNOTATION_KEY] = []
-        request.annotations[CONSUMERS_ANNOTATION_KEY] = []
-    else:
-        for obj, consumed in request.annotations[CONSUMED_ANNOTATION_KEY]:
-            if obj == context:
-                return
-    orgStack = request.getTraversalStack()
-    cons = [cons for name, cons in getStackConsumers(
-        context, request)]
-    newStack = request.getTraversalStack()
-    if newStack != orgStack:
-        consumed = request.annotations[CONSUMED_ANNOTATION_KEY]
-        numItems = len(orgStack)-len(newStack)
-        vhStack = VHStack(request)
-        vhStack.prepare()
-        stack = request.getTraversalStack()
-        items = orgStack[len(stack):len(stack)+numItems]
-        vhStack.reset()
-        items.reverse()
-        consumed.append((context, items))
-    request.annotations[CONSUMERS_ANNOTATION_KEY].extend(cons)
-
-
-def _encode(v, _safe='@+'):
-    return urllib.quote(v.encode('utf-8'), _safe)
-
-
-def unconsumedURL(context, request):
-    url = absoluteURL(context, request)
-    consumed = request.annotations.get(CONSUMED_ANNOTATION_KEY)
-    if not consumed:
-        return url
-    inserts = []
-    for obj, names in consumed:
-        if obj is context:
-            # only calculate once
-            objURL = url
-        else:
-            objURL = absoluteURL(obj, request)
-        if not url.startswith(objURL):
-            # we are further down
-            break
-        names = '/' + '/'.join(map(_encode, names))
-        inserts.append((len(objURL), names))
-
-    offset = 0
-    for i, s in inserts:
-        oi = i + offset
-        pre = url[:oi]
-        post = url[oi:]
-        url = pre + s + post
-        offset += len(s)
-    return url
-
-class UnconsumedURL(BrowserView):
-    # XXX test this
-    def __unicode__(self):
-        return urllib.unquote(self.__str__()).decode('utf-8')
-
-    def __str__(self):
-        return unconsumedURL(self.context, self.request)
-
-    __call__ = __str__
-
-
-class VHStack:
-    """Helper class to work around the special case with virtual hosts"""
-
-    def __init__(self, request):
-        self.request = request
-        self.vh = []
-
-    def prepare(self):
-        if not self.vh:
-            stack = self.request.getTraversalStack()
-            if not stack:
-                return
-            name = stack[-1]
-            if name.startswith('++vh++'):
-                while True:
-                    self.vh.append(stack.pop())
-                    if name == '++':
-                        break
-                    if not stack:
-                        break
-                    name = stack[-1]
-                # set stack without virtual host entries
-                self.request.setTraversalStack(stack)
-
-    def reset(self):
-        if self.vh:
-            stack = self.request.getTraversalStack()
-            while self.vh:
-                stack.append(self.vh.pop())
-            self.request.setTraversalStack(stack)
-

Copied: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/traversing.py (from rev 95978, z3c.traverser/trunk/src/z3c/traverser/stackinfo/traversing.py)
===================================================================
--- z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/traversing.py	                        (rev 0)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/traversing.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -0,0 +1,134 @@
+import urllib
+
+from zope import component
+from zope.proxy import sameProxiedObjects
+from zope.publisher.browser import BrowserView
+from zope.publisher.interfaces import NotFound
+from zope.traversing.browser.absoluteurl import absoluteURL
+
+import interfaces
+
+CONSUMERS_ANNOTATION_KEY='z3c.traverser.consumers'
+CONSUMED_ANNOTATION_KEY='z3c.traverser.consumed'
+
+def getStackConsumers(context, request):
+    """consumes the stack"""
+    vhStack = VHStack(request)
+    while True:
+        vhStack.prepare()
+        stack = request.getTraversalStack()
+        if not stack:
+            break
+        name = stack[-1]
+        consumer = component.queryMultiAdapter(
+                        (context, request),
+                        interface=interfaces.ITraversalStackConsumer,
+                        name=name)
+        if consumer is None:
+            break
+        try:
+            consumer.consume()
+        except IndexError:
+            raise NotFound(context, name, request)
+        vhStack.reset()
+        yield (name, consumer)
+    vhStack.reset()
+
+
+def applyStackConsumers(context, request):
+    if not request.annotations.has_key(CONSUMED_ANNOTATION_KEY):
+        request.annotations[CONSUMED_ANNOTATION_KEY] = []
+        request.annotations[CONSUMERS_ANNOTATION_KEY] = []
+    else:
+        for obj, consumed in request.annotations[CONSUMED_ANNOTATION_KEY]:
+            if sameProxiedObjects(obj, context):
+                return
+    orgStack = request.getTraversalStack()
+    cons = [cons for name, cons in getStackConsumers(
+        context, request)]
+    newStack = request.getTraversalStack()
+    if newStack != orgStack:
+        consumed = request.annotations[CONSUMED_ANNOTATION_KEY]
+        numItems = len(orgStack)-len(newStack)
+        vhStack = VHStack(request)
+        vhStack.prepare()
+        stack = request.getTraversalStack()
+        items = orgStack[len(stack):len(stack)+numItems]
+        vhStack.reset()
+        items.reverse()
+        consumed.append((context, items))
+    request.annotations[CONSUMERS_ANNOTATION_KEY].extend(cons)
+
+
+def _encode(v, _safe='@+'):
+    return urllib.quote(v.encode('utf-8'), _safe)
+
+
+def unconsumedURL(context, request):
+    url = absoluteURL(context, request)
+    consumed = request.annotations.get(CONSUMED_ANNOTATION_KEY)
+    if not consumed:
+        return url
+    inserts = []
+    for obj, names in consumed:
+        if obj is context:
+            # only calculate once
+            objURL = url
+        else:
+            objURL = absoluteURL(obj, request)
+        if not url.startswith(objURL):
+            # we are further down
+            break
+        names = '/' + '/'.join(map(_encode, names))
+        inserts.append((len(objURL), names))
+
+    offset = 0
+    for i, s in inserts:
+        oi = i + offset
+        pre = url[:oi]
+        post = url[oi:]
+        url = pre + s + post
+        offset += len(s)
+    return url
+
+class UnconsumedURL(BrowserView):
+
+    def __unicode__(self):
+        return urllib.unquote(self.__str__()).decode('utf-8')
+
+    def __str__(self):
+        return unconsumedURL(self.context, self.request)
+
+    __call__ = __str__
+
+class VHStack:
+    """Helper class to work around the special case with virtual hosts"""
+
+    def __init__(self, request):
+        self.request = request
+        self.vh = []
+
+    def prepare(self):
+        if not self.vh:
+            stack = self.request.getTraversalStack()
+            if not stack:
+                return
+            name = stack[-1]
+            if name.startswith('++vh++'):
+                while True:
+                    self.vh.append(stack.pop())
+                    if name == '++':
+                        break
+                    if not stack:
+                        break
+                    name = stack[-1]
+                # set stack without virtual host entries
+                self.request.setTraversalStack(stack)
+
+    def reset(self):
+        if self.vh:
+            stack = self.request.getTraversalStack()
+            while self.vh:
+                stack.append(self.vh.pop())
+            self.request.setTraversalStack(stack)
+

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/z3c.traverser.stackinfo-configure.zcml
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/stackinfo/z3c.traverser.stackinfo-configure.zcml	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/stackinfo/z3c.traverser.stackinfo-configure.zcml	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1 +0,0 @@
-<include package="z3c.traverser.stackinfo"/>
\ No newline at end of file

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/browser.py
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/viewlet/browser.py	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/browser.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,76 +0,0 @@
-from zope.traversing.browser import absoluteurl
-import zope.component
-import urllib
-from zope.security.proxy import removeSecurityProxy
-from zope.publisher.browser import BrowserView
-from zope.contentprovider.interfaces import BeforeUpdateEvent
-from zope import event
-
-class ViewletAbsoluteURL(absoluteurl.AbsoluteURL):
-
-    def __str__(self):
-        context = removeSecurityProxy(self.context)
-        request = self.request
-
-        # The application URL contains all the namespaces that are at the
-        # beginning of the URL, such as skins, virtual host specifications and
-        # so on.
-
-        container = getattr(context, 'manager', None)
-        if container is None:
-            raise TypeError(absoluteurl._insufficientContext)
-        url = str(zope.component.getMultiAdapter((container, request),
-                                                 name='absolute_url'))
-        name = self._getContextName(context)
-        if name is None:
-            raise TypeError(absoluteurl._insufficientContext)
-
-        if name:
-            url += '/' + urllib.quote(name.encode('utf-8'),
-                                      absoluteurl._safe)
-
-        return url
-
-    def _getContextName(self, context):
-        name = getattr(context, '__name__', None)
-        return u'++viewlet++' + name
-
-
-    __call__ = __str__
-
-class ViewletManagerAbsoluteURL(absoluteurl.AbsoluteURL):
-
-    def __str__(self):
-        context = self.context
-        request = self.request
-
-        container = getattr(context, '__parent__', None)
-        if container is None:
-            raise TypeError(absoluteurl._insufficientContext)
-        url = str(zope.component.getMultiAdapter((container, request),
-                                                 name='absolute_url'))
-        name = self._getContextName(context)
-        if name is None:
-            raise TypeError(absoluteurl._insufficientContext)
-
-        if name:
-            url += '/' + urllib.quote(name.encode('utf-8'),
-                                      absoluteurl._safe)
-
-        return url
-
-
-    def _getContextName(self, context):
-        name = getattr(context, '__name__', None)
-        return u'++manager++' + name
-
-    __call__ = __str__
-
-class ViewletView(BrowserView):
-
-    def __call__(self):
-        event.notify(BeforeUpdateEvent(self.context, self.request))
-        self.context.update()
-        return self.context.render()
-    
-        

Copied: z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/browser.py (from rev 95983, z3c.traverser/trunk/src/z3c/traverser/viewlet/browser.py)
===================================================================
--- z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/browser.py	                        (rev 0)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/browser.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -0,0 +1,77 @@
+import urllib
+
+import zope.component
+from zope import event
+from zope.contentprovider.interfaces import BeforeUpdateEvent
+from zope.publisher.browser import BrowserView
+from zope.security.proxy import removeSecurityProxy
+from zope.traversing.browser import absoluteurl
+
+class ViewletAbsoluteURL(absoluteurl.AbsoluteURL):
+
+    def __str__(self):
+        context = removeSecurityProxy(self.context)
+        request = self.request
+
+        # The application URL contains all the namespaces that are at the
+        # beginning of the URL, such as skins, virtual host specifications and
+        # so on.
+
+        container = getattr(context, 'manager', None)
+        if container is None:
+            raise TypeError(absoluteurl._insufficientContext)
+        url = str(zope.component.getMultiAdapter((container, request),
+                                                 name='absolute_url'))
+        name = self._getContextName(context)
+        if name is None:
+            raise TypeError(absoluteurl._insufficientContext)
+
+        if name:
+            url += '/' + urllib.quote(name.encode('utf-8'),
+                                      absoluteurl._safe)
+
+        return url
+
+    def _getContextName(self, context):
+        name = getattr(context, '__name__', None)
+        return u'++viewlet++' + name
+
+
+    __call__ = __str__
+
+class ViewletManagerAbsoluteURL(absoluteurl.AbsoluteURL):
+
+    def __str__(self):
+        context = self.context
+        request = self.request
+
+        container = getattr(context, '__parent__', None)
+        if container is None:
+            raise TypeError(absoluteurl._insufficientContext)
+        url = str(zope.component.getMultiAdapter((container, request),
+                                                 name='absolute_url'))
+        name = self._getContextName(context)
+        if name is None:
+            raise TypeError(absoluteurl._insufficientContext)
+
+        if name:
+            url += '/' + urllib.quote(name.encode('utf-8'),
+                                      absoluteurl._safe)
+
+        return url
+
+
+    def _getContextName(self, context):
+        name = getattr(context, '__name__', None)
+        return u'++manager++' + name
+
+    __call__ = __str__
+
+class ViewletView(BrowserView):
+
+    def __call__(self):
+        event.notify(BeforeUpdateEvent(self.context, self.request))
+        self.context.update()
+        return self.context.render()
+    
+        

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/ftesting.zcml
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/viewlet/ftesting.zcml	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/ftesting.zcml	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,140 +0,0 @@
-<configure xmlns="http://namespaces.zope.org/zope"
-           xmlns:browser="http://namespaces.zope.org/browser"
-           xmlns:meta="http://namespaces.zope.org/meta"
-           xmlns:zcml="http://namespaces.zope.org/zcml"
-           i18n_domain="zope">
-
-  <include
-      zcml:condition="installed zope.app.zcmlfiles"
-      package="zope.app.zcmlfiles"
-      />
-  <include
-      zcml:condition="not-installed zope.app.zcmlfiles"
-      package="zope.app"
-      />
-
-
-  <include package="zope.viewlet" file="meta.zcml"/>
-  <include package="zope.app.securitypolicy" file="meta.zcml" />
-
-
-  <include package="zope.app.authentication" />
-
-  <securityPolicy
-      component="zope.securitypolicy.zopepolicy.ZopeSecurityPolicy" />
-
-  <include package="zope.app.securitypolicy" />
-
-  <role id="zope.Anonymous" title="Everybody"
-        description="All users have this role implicitly" />
-
-  <role id="zope.Manager" title="Site Manager" />
-
-
-  <principal
-   id="zope.manager"
-   title="Administrator"
-   login="mgr"
-   password="mgrpw" />
-  <grant
-   role="zope.Manager"
-   principal="zope.manager"
-   />
-
-  <unauthenticatedPrincipal
-    id="zope.anybody"
-    title="Unauthenticated User" />
-
-  <unauthenticatedGroup
-    id="zope.Anybody"
-    title="Unauthenticated Users"
-    />
-
-  <authenticatedGroup
-    id="zope.Authenticated"
-    title="Authenticated Users"
-    />
-
-  <everybodyGroup
-    id="zope.Everybody"
-    title="All Users"
-    />
-
-  <include package="zope.contentprovider"/>
-  <include package="zope.viewlet"/>
-  <include package="z3c.traverser.viewlet"/>
-
-  <grant permission="zope.View"
-         role="zope.Anonymous" />
-
-  <grantAll role="zope.Manager" />
-
-  <configure package="z3c.traverser.viewlet.testing">
-  <browser:viewlet
-      name="MyViewlet"
-      manager=".app.IMyManager"
-      class=".app.MyViewlet"
-      permission="zope.Public"/>
-
-  <browser:viewletManager
-      name="IMyManager"
-      provides=".app.IMyManager"
-      permission="zope.Public"
-      />
-
-  <browser:page
-      for="*"
-      name="test.html"
-      template="test.pt"
-      permission="zope.Public"
-      />
-
-  <!-- nested viewlet manager -->
-  <browser:page
-      for="*"
-      name="nested.html"
-      template="nested.pt"
-      permission="zope.Public"
-      />
-
-  <browser:viewletManager
-      name="IOuterManager"
-      provides=".app.IOuterManager"
-      permission="zope.Public"
-      />
-
-  <browser:viewlet
-      for="zope.app.component.interfaces.ISite"
-      name="OuterViewlet"
-      manager=".app.IOuterManager"
-      class=".app.OuterViewlet"
-      permission="zope.Public"/>
-
-  <browser:viewletManager
-      name="IInnerManager"
-      provides=".app.IInnerManager"
-      permission="zope.Public"
-      />
-
-  <browser:viewlet
-      for="zope.app.component.interfaces.ISite"
-      name="InnerViewlet"
-      manager=".app.IInnerManager"
-      class=".app.InnerViewlet"
-      permission="zope.Public"/>
-
-  <browser:viewletManager
-      name="IMostInnerManager"
-      provides=".app.IMostInnerManager"
-      permission="zope.Public"
-      />
-
-  <browser:viewlet
-      for="zope.app.component.interfaces.ISite"
-      name="MostInnerViewlet"
-      manager=".app.IMostInnerManager"
-      class=".app.MostInnerViewlet"
-      permission="zope.Public"/>
-
-  </configure>
-</configure>

Copied: z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/ftesting.zcml (from rev 95978, z3c.traverser/trunk/src/z3c/traverser/viewlet/ftesting.zcml)
===================================================================
--- z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/ftesting.zcml	                        (rev 0)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/ftesting.zcml	2009-02-02 15:44:41 UTC (rev 95984)
@@ -0,0 +1,140 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:browser="http://namespaces.zope.org/browser"
+           xmlns:meta="http://namespaces.zope.org/meta"
+           xmlns:zcml="http://namespaces.zope.org/zcml"
+           i18n_domain="zope">
+
+  <include
+      zcml:condition="installed zope.app.zcmlfiles"
+      package="zope.app.zcmlfiles"
+      />
+  <include
+      zcml:condition="not-installed zope.app.zcmlfiles"
+      package="zope.app"
+      />
+
+
+  <include package="zope.viewlet" file="meta.zcml"/>
+  <include package="zope.app.securitypolicy" file="meta.zcml" />
+
+
+  <include package="zope.app.authentication" />
+
+  <securityPolicy
+      component="zope.securitypolicy.zopepolicy.ZopeSecurityPolicy" />
+
+  <include package="zope.app.securitypolicy" />
+
+  <role id="zope.Anonymous" title="Everybody"
+        description="All users have this role implicitly" />
+
+  <role id="zope.Manager" title="Site Manager" />
+
+
+  <principal
+   id="zope.manager"
+   title="Administrator"
+   login="mgr"
+   password="mgrpw" />
+  <grant
+   role="zope.Manager"
+   principal="zope.manager"
+   />
+
+  <unauthenticatedPrincipal
+    id="zope.anybody"
+    title="Unauthenticated User" />
+
+  <unauthenticatedGroup
+    id="zope.Anybody"
+    title="Unauthenticated Users"
+    />
+
+  <authenticatedGroup
+    id="zope.Authenticated"
+    title="Authenticated Users"
+    />
+
+  <everybodyGroup
+    id="zope.Everybody"
+    title="All Users"
+    />
+
+  <include package="zope.contentprovider"/>
+  <include package="zope.viewlet"/>
+  <include package="z3c.traverser.viewlet"/>
+
+  <grant permission="zope.View"
+         role="zope.Anonymous" />
+
+  <grantAll role="zope.Manager" />
+
+  <configure package="z3c.traverser.viewlet.testing">
+  <browser:viewlet
+      name="MyViewlet"
+      manager=".app.IMyManager"
+      class=".app.MyViewlet"
+      permission="zope.Public"/>
+
+  <browser:viewletManager
+      name="IMyManager"
+      provides=".app.IMyManager"
+      permission="zope.Public"
+      />
+
+  <browser:page
+      for="*"
+      name="test.html"
+      template="test.pt"
+      permission="zope.Public"
+      />
+
+  <!-- nested viewlet manager -->
+  <browser:page
+      for="*"
+      name="nested.html"
+      template="nested.pt"
+      permission="zope.Public"
+      />
+
+  <browser:viewletManager
+      name="IOuterManager"
+      provides=".app.IOuterManager"
+      permission="zope.Public"
+      />
+
+  <browser:viewlet
+      for="zope.location.interfaces.ISite"
+      name="OuterViewlet"
+      manager=".app.IOuterManager"
+      class=".app.OuterViewlet"
+      permission="zope.Public"/>
+
+  <browser:viewletManager
+      name="IInnerManager"
+      provides=".app.IInnerManager"
+      permission="zope.Public"
+      />
+
+  <browser:viewlet
+      for="zope.location.interfaces.ISite"
+      name="InnerViewlet"
+      manager=".app.IInnerManager"
+      class=".app.InnerViewlet"
+      permission="zope.Public"/>
+
+  <browser:viewletManager
+      name="IMostInnerManager"
+      provides=".app.IMostInnerManager"
+      permission="zope.Public"
+      />
+
+  <browser:viewlet
+      for="zope.location.interfaces.ISite"
+      name="MostInnerViewlet"
+      manager=".app.IMostInnerManager"
+      class=".app.MostInnerViewlet"
+      permission="zope.Public"/>
+
+  </configure>
+</configure>

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/namespace.py
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/viewlet/namespace.py	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/namespace.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,58 +0,0 @@
-from zope.traversing.namespace import SimpleHandler
-from zope import component
-from zope.publisher.interfaces import NotFound
-from zope.viewlet.interfaces import IViewletManager
-from zope.security.proxy import removeSecurityProxy
-
-class ViewletViewletManagerHandler(SimpleHandler):
-
-    def __init__(self, context, request=None):
-        self.context = context
-        self.request = request
-
-    def traverse(self, name, ignored):
-        context = removeSecurityProxy(self.context).context
-        provider = component.queryMultiAdapter(
-            (context, self.request, self.context),
-            IViewletManager, name)
-        if provider is None:
-            raise NotFound(self.context, name, self.request)
-
-        return provider
-
-
-class ViewletManagerHandler(SimpleHandler):
-
-    def __init__(self, context, request=None):
-        self.context = context
-        self.request = request
-
-    def traverse(self, name, ignored):
-        context = self.context.__parent__
-        provider = component.queryMultiAdapter(
-            (context, self.request, self.context),
-            IViewletManager, name)
-        if provider is None:
-            raise NotFound(self.context, name, self.request)
-        return provider
-
-
-class ViewletHandler(SimpleHandler):
-
-    def __init__(self, context, request=None):
-        self.context = context
-        self.request = request
-
-    def traverse(self, name, ignored):
-        # Try to look up the viewlet
-        viewlet = self.context.get(name)
-        if viewlet is None:
-            raise NotFound(self.context, name, self.request)
-        viewlet = removeSecurityProxy(viewlet)
-        # hack: somehow in the viewlet metaconfigure it makes the
-        # viewlet class a IBrowserPublisher, which assumes that we
-        # have a call in browserdefault, so we have to replace this
-        # method.
-        viewlet.browserDefault = lambda r: (viewlet, ('index.html',))
-        return viewlet
-

Copied: z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/namespace.py (from rev 95983, z3c.traverser/trunk/src/z3c/traverser/viewlet/namespace.py)
===================================================================
--- z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/namespace.py	                        (rev 0)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/namespace.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -0,0 +1,58 @@
+from zope import component
+from zope.publisher.interfaces import NotFound
+from zope.security.proxy import removeSecurityProxy
+from zope.traversing.namespace import SimpleHandler
+from zope.viewlet.interfaces import IViewletManager
+
+class ViewletViewletManagerHandler(SimpleHandler):
+
+    def __init__(self, context, request=None):
+        self.context = context
+        self.request = request
+
+    def traverse(self, name, ignored):
+        context = removeSecurityProxy(self.context).context
+        provider = component.queryMultiAdapter(
+            (context, self.request, self.context),
+            IViewletManager, name)
+        if provider is None:
+            raise NotFound(self.context, name, self.request)
+
+        return provider
+
+
+class ViewletManagerHandler(SimpleHandler):
+
+    def __init__(self, context, request=None):
+        self.context = context
+        self.request = request
+
+    def traverse(self, name, ignored):
+        context = self.context.__parent__
+        provider = component.queryMultiAdapter(
+            (context, self.request, self.context),
+            IViewletManager, name)
+        if provider is None:
+            raise NotFound(self.context, name, self.request)
+        return provider
+
+
+class ViewletHandler(SimpleHandler):
+
+    def __init__(self, context, request=None):
+        self.context = context
+        self.request = request
+
+    def traverse(self, name, ignored):
+        # Try to look up the viewlet
+        viewlet = self.context.get(name)
+        if viewlet is None:
+            raise NotFound(self.context, name, self.request)
+        viewlet = removeSecurityProxy(viewlet)
+        # hack: somehow in the viewlet metaconfigure it makes the
+        # viewlet class a IBrowserPublisher, which assumes that we
+        # have a call in browserdefault, so we have to replace this
+        # method.
+        viewlet.browserDefault = lambda r: (viewlet, ('index.html',))
+        return viewlet
+

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/test.pt
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/viewlet/test.pt	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/test.pt	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,5 +0,0 @@
-<html>
-  <body>
-    <div tal:content="structure provider:IMyManager"/>
-  </body>
-</html>
\ No newline at end of file

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/tests.py
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/viewlet/tests.py	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/tests.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1,35 +0,0 @@
-import doctest
-import unittest
-from zope.testing.doctestunit import DocFileSuite, DocFileSuite
-from zope.app.testing import setup
-import zope.traversing.testing
-from zope.traversing.testing import browserView
-from zope.traversing.browser import AbsoluteURL, SiteAbsoluteURL
-from zope.traversing.interfaces import IContainmentRoot
-from zope.traversing.browser.interfaces import IAbsoluteURL
-
-def setUp(test):
-    root = setup.placefulSetUp(True)
-    zope.traversing.testing.setUp()
-    test.globs['root'] = root
-
-    browserView(None, 'absolute_url', AbsoluteURL)
-    browserView(IContainmentRoot, 'absolute_url', SiteAbsoluteURL)
-    browserView(None, '', AbsoluteURL, providing=IAbsoluteURL)
-    browserView(IContainmentRoot, '', SiteAbsoluteURL, providing=IAbsoluteURL)
-
-def tearDown(test):
-    setup.placefulTearDown()
-
-def test_suite():
-    
-    return unittest.TestSuite(
-        (
-        DocFileSuite('README.txt',
-                     setUp=setUp, tearDown=tearDown,
-                     optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
-                     ),
-        ))
-
-if __name__ == '__main__':
-    unittest.main(defaultTest='test_suite')

Copied: z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/tests.py (from rev 95983, z3c.traverser/trunk/src/z3c/traverser/viewlet/tests.py)
===================================================================
--- z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/tests.py	                        (rev 0)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/tests.py	2009-02-02 15:44:41 UTC (rev 95984)
@@ -0,0 +1,36 @@
+import doctest
+import unittest
+
+import zope.traversing.testing
+from zope.app.testing import setup
+from zope.testing.doctestunit import DocFileSuite, DocFileSuite
+from zope.traversing.browser import AbsoluteURL, SiteAbsoluteURL
+from zope.traversing.browser.interfaces import IAbsoluteURL
+from zope.traversing.interfaces import IContainmentRoot
+from zope.traversing.testing import browserView
+
+def setUp(test):
+    root = setup.placefulSetUp(True)
+    zope.traversing.testing.setUp()
+    test.globs['root'] = root
+
+    browserView(None, 'absolute_url', AbsoluteURL)
+    browserView(IContainmentRoot, 'absolute_url', SiteAbsoluteURL)
+    browserView(None, '', AbsoluteURL, providing=IAbsoluteURL)
+    browserView(IContainmentRoot, '', SiteAbsoluteURL, providing=IAbsoluteURL)
+
+def tearDown(test):
+    setup.placefulTearDown()
+
+def test_suite():
+    
+    return unittest.TestSuite(
+        (
+        DocFileSuite('README.txt',
+                     setUp=setUp, tearDown=tearDown,
+                     optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+                     ),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Deleted: z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/z3c.traverser.viewlet-configure.zcml
===================================================================
--- z3c.traverser/trunk/src/z3c/traverser/viewlet/z3c.traverser.viewlet-configure.zcml	2009-02-02 12:59:51 UTC (rev 95968)
+++ z3c.traverser/tags/0.2.4/src/z3c/traverser/viewlet/z3c.traverser.viewlet-configure.zcml	2009-02-02 15:44:41 UTC (rev 95984)
@@ -1 +0,0 @@
-<include package="z3c.traverser.viewlet"/>
\ No newline at end of file



More information about the Checkins mailing list