[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