Skip to content

Commit

Permalink
implemented unconsumed_url, which returns the absolute_url but with t…
Browse files Browse the repository at this point in the history
…he stack info
  • Loading branch information
dobe committed Oct 2, 2006
1 parent 60cbc17 commit 6cb31e5
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 8 deletions.
27 changes: 25 additions & 2 deletions src/z3c/traverser/stackinfo/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ 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.ANNOTATION_KEY]
>>> request.annotations[traversing.CONSUMERS_ANNOTATION_KEY]
[<KeyValueConsumer named u'kv'>,
<KeyValueConsumer named u'kv'>]

Expand All @@ -154,11 +154,34 @@ to ITraversalStackInfo.

>>> 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

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'

8 changes: 8 additions & 0 deletions src/z3c/traverser/stackinfo/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,13 @@
<class class=".consumer.TraversalStackInfo">
<allow interface=".interfaces.ITraversalStackInfo"/>
</class>

<view
for="*"
name="unconsumed_url"
factory=".traversing.UnconsumedURL"
type="zope.publisher.interfaces.http.IHTTPRequest"
permission="zope.Public"
/>

</configure>
8 changes: 6 additions & 2 deletions src/z3c/traverser/stackinfo/consumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
@component.adapter(IBrowserRequest)
@interface.implementer(interfaces.ITraversalStackInfo)
def requestTraversalStackInfo(request):
cons = request.annotations.get(traversing.ANNOTATION_KEY, [])
cons = request.annotations.get(traversing.CONSUMERS_ANNOTATION_KEY, [])
return TraversalStackInfo(cons)

class TraversalStackInfo(tuple):
Expand All @@ -25,9 +25,13 @@ def __init__(self, context, request):
def consume(self):
stack = self.request.getTraversalStack()
self.__name__ = stack.pop()
consumed = [self.__name__]
for name in self.arguments:
setattr(self, name, stack.pop())
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__,
Expand Down
6 changes: 5 additions & 1 deletion src/z3c/traverser/stackinfo/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
import unittest
from zope.testing.doctestunit import DocFileSuite, DocFileSuite
from zope.app.testing import setup
import zope.traversing.testing

def setUp(test):
setup.placefulSetUp()
root = setup.placefulSetUp(True)
zope.traversing.testing.setUp()
test.globs['root'] = root

def tearDown(test):
setup.placefulTearDown()
Expand All @@ -14,6 +17,7 @@ def test_suite():
return unittest.TestSuite(
(
DocFileSuite('README.txt',
setUp=setUp, tearDown=tearDown,
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
),
))
Expand Down
60 changes: 57 additions & 3 deletions src/z3c/traverser/stackinfo/traversing.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
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

ANNOTATION_KEY='z3c.traverser.consumers'
CONSUMERS_ANNOTATION_KEY='z3c.traverser.consumers'
CONSUMED_ANNOTATION_KEY='z3c.traverser.consumed'

def getStackConsumers(context, request):
"""consumes the stack"""
Expand All @@ -25,5 +29,55 @@ def getStackConsumers(context, request):
break

def applyStackConsumers(context, request):
cons = [cons for name, cons in getStackConsumers(context, request)]
request.annotations[ANNOTATION_KEY] = cons
if not request.annotations.has_key(CONSUMED_ANNOTATION_KEY):
request.annotations[CONSUMED_ANNOTATION_KEY] = []
orgStack = request.getTraversalStack()
cons = [cons for name, cons in getStackConsumers(
context, request)]
newStack = request.getTraversalStack()
if newStack != orgStack:
consumed = request.annotations[CONSUMED_ANNOTATION_KEY]
items = orgStack[len(newStack):]
items.reverse()
consumed.append((context, items))
request.annotations[CONSUMERS_ANNOTATION_KEY] = cons

def _encode(v, _safe='@+'):
return urllib.quote(v.encode('utf-8'), _safe)

def unconsumedURL(context, request):

consumed = list(request.annotations.get(CONSUMED_ANNOTATION_KEY))
if not consumed:
return absoluteURL(context, request)
from zope.traversing import api

from zope.traversing.interfaces import IContainmentRoot
name = api.getName(context)
items = name and [name] or []
for obj, names in consumed:
if obj == context:
items.extend(names)
break
if IContainmentRoot.providedBy(context):
base = absoluteURL(context, request)
else:
base = unconsumedURL(api.getParent(context), request)
items = map(_encode, items)
if not base.endswith('/'):
base += '/'
return base + '/'.join(items)

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__




0 comments on commit 6cb31e5

Please sign in to comment.