[Checkins] SVN: grok/trunk/src/grok/ Fix fallback behaviour of grok.Traverser in case of containers. When you

Philipp von Weitershausen philikon at philikon.de
Tue Apr 17 14:01:37 EDT 2007


Log message for revision 74208:
  Fix fallback behaviour of grok.Traverser in case of containers. When you
  had a custom traverser registered for a container and it would fall back
  on the standard lookup behaviour, views would be looked up *before* items
  in the container. This isn't the standard Zope 3 behaviour.
  
  Also, padded out/corrected an XXX comment concerning the fact that
  grok.Traverser even has to be aware of containers. (It needs to be
  aware of views, that's perfectly acceptable).
  

Changed:
  U   grok/trunk/src/grok/components.py
  U   grok/trunk/src/grok/ftests/traversal/containertraverser.py
  A   grok/trunk/src/grok/ftests/traversal/items_before_views.py

-=-
Modified: grok/trunk/src/grok/components.py
===================================================================
--- grok/trunk/src/grok/components.py	2007-04-17 17:55:30 UTC (rev 74207)
+++ grok/trunk/src/grok/components.py	2007-04-17 18:01:37 UTC (rev 74208)
@@ -320,18 +320,19 @@
         if subob is not None:
             return subob
 
-        # XXX special logic here to deal with views and containers.
-        # would be preferrable if we could fall back on normal Zope
-        # traversal behavior
-        view = component.queryMultiAdapter((self.context, request), name=name)
-        if view:
-            return view
-
+        # XXX Special logic here to deal with containers.  It would be
+        # good if we wouldn't have to do this here. One solution is to
+        # rip this out and make you subclass ContainerTraverser if you
+        # wanted to override the traversal behaviour of containers.
         if IReadContainer.providedBy(self.context):
             item = self.context.get(name)
             if item is not None:
                 return item
 
+        view = component.queryMultiAdapter((self.context, request), name=name)
+        if view is not None:
+            return view
+
         raise NotFound(self.context, name, request)
 
     def traverse(self, name):

Modified: grok/trunk/src/grok/ftests/traversal/containertraverser.py
===================================================================
--- grok/trunk/src/grok/ftests/traversal/containertraverser.py	2007-04-17 17:55:30 UTC (rev 74207)
+++ grok/trunk/src/grok/ftests/traversal/containertraverser.py	2007-04-17 18:01:37 UTC (rev 74208)
@@ -71,7 +71,7 @@
         if name == 'special':
             return Special()
         return None
-    
+
 class Mammoth(grok.Model):
     def __init__(self, name):
         self.name = name

Added: grok/trunk/src/grok/ftests/traversal/items_before_views.py
===================================================================
--- grok/trunk/src/grok/ftests/traversal/items_before_views.py	2007-04-17 17:55:30 UTC (rev 74207)
+++ grok/trunk/src/grok/ftests/traversal/items_before_views.py	2007-04-17 18:01:37 UTC (rev 74208)
@@ -0,0 +1,67 @@
+"""
+Containers can have an explicit traverser associated with them.  The
+behaviour falls back to basic container traversal if the 'traverse'
+method returns None. Normal behaviour also means that the standard
+Zope 3 paradigm"items before views" is supported in the fallback.
+
+  >>> import grok
+  >>> from grok.ftests.traversal.items_before_views import Herd, Mammoth
+  >>> grok.grok('grok.ftests.traversal.items_before_views')
+  >>> getRootFolder()["herd"] = herd = Herd()
+  >>> herd['manfred'] = Mammoth('Manfred')
+  >>> herd['ellie'] = Mammoth('Ellie')
+
+  >>> from zope.testbrowser.testing import Browser
+  >>> browser = Browser()
+  >>> browser.handleErrors = False
+
+When we look up 'manfred', we'll get the Mammoth object as expected:
+
+  >>> browser.open("http://localhost/herd/manfred")
+  >>> print browser.contents
+  Hello Manfred
+
+When we look up 'ellie', we also get a Mammoth object and not the
+Ellie view:
+
+  >>> browser.open("http://localhost/herd/ellie")
+  >>> print browser.contents
+  Hello Ellie
+
+We can, of course, get to the Ellie view explicitly:
+
+  >>> browser.open("http://localhost/herd/@@ellie")
+  >>> print browser.contents
+  Hi, it's me, the Ellie view!
+
+"""
+import grok
+
+class Herd(grok.Container):
+    pass
+
+class Traverser(grok.Traverser):
+    grok.context(Herd)
+
+    def traverse(self, name):
+        # we don't really need to do anything here as we want to test
+        # the fallback behaviour
+        pass
+
+class Ellie(grok.View):
+    grok.context(Herd)
+    grok.name('ellie')
+
+    def render(self):
+        return "Hi, it's me, the Ellie view!"
+
+class Mammoth(grok.Model):
+    def __init__(self, name):
+        self.name = name
+
+class MammothIndex(grok.View):
+    grok.context(Mammoth)
+    grok.name('index')
+
+    def render(self):
+        return "Hello " + self.context.name.title()


Property changes on: grok/trunk/src/grok/ftests/traversal/items_before_views.py
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the Checkins mailing list