[Checkins] SVN: grok/trunk/src/grok/ Make sure grok.Traverser works with containers too, not just model-level

Martijn Faassen faassen at infrae.com
Fri Dec 1 16:30:16 EST 2006


Log message for revision 71367:
  Make sure grok.Traverser works with containers too, not just model-level
  traverse method.
  

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

-=-
Modified: grok/trunk/src/grok/_grok.py
===================================================================
--- grok/trunk/src/grok/_grok.py	2006-12-01 19:51:52 UTC (rev 71366)
+++ grok/trunk/src/grok/_grok.py	2006-12-01 21:30:16 UTC (rev 71367)
@@ -111,7 +111,6 @@
 
     context = util.determine_module_context(module_info,
                                             components[grok.Model])
-
     register_models(components[grok.Model])
     register_adapters(context, components[grok.Adapter])
     register_multiadapters(components[grok.MultiAdapter])
@@ -143,10 +142,12 @@
     module = module_info.getModule()
     for name in dir(module):
         obj = getattr(module, name)
-
+        # we don't care about picking up module-level annotations from grok
+        if name.startswith('__grok_'):
+            continue        
         if not util.defined_locally(obj, module_info.dotted_name):
             continue
-
+        
         if isinstance(obj, grok.PageTemplate):
             templates.register(name, obj)
             obj._annotateGrokInfo(name, module_info.dotted_name)

Modified: grok/trunk/src/grok/components.py
===================================================================
--- grok/trunk/src/grok/components.py	2006-12-01 19:51:52 UTC (rev 71366)
+++ grok/trunk/src/grok/components.py	2006-12-01 21:30:16 UTC (rev 71367)
@@ -41,6 +41,7 @@
     PageTemplateResourceFactory
 from zope.app.container.btree import BTreeContainer
 from zope.app.container.contained import Contained
+from zope.app.container.interfaces import IReadContainer
 from zope.app.component.site import SiteManagerContainer
 
 from grok import util, security, interfaces
@@ -217,10 +218,18 @@
         if subob:
             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
 
+        if IReadContainer.providedBy(self.context):
+            item = self.context.get(name)
+            if item:
+                return item
+    
         raise NotFound(self.context, name, request)
 
     def traverse(self, name):

Added: grok/trunk/src/grok/ftests/traversal/containertraverser.py
===================================================================
--- grok/trunk/src/grok/ftests/traversal/containertraverser.py	2006-12-01 19:51:52 UTC (rev 71366)
+++ grok/trunk/src/grok/ftests/traversal/containertraverser.py	2006-12-01 21:30:16 UTC (rev 71367)
@@ -0,0 +1,89 @@
+"""
+Containers can also have an explicit traverser associated with them.
+The behavior falls back to basic container traversal if the 'traverse'
+method returns None:
+
+  >>> import grok
+  >>> from grok.ftests.traversal.containertraverser import Herd, Mammoth
+  >>> grok.grok('grok.ftests.traversal.containertraverser')
+  >>> getRootFolder()["herd"] = herd = Herd()
+  >>> herd['manfred'] = Mammoth('Manfred')
+  >>> herd['ellie'] = Mammoth('Ellie')
+
+Let's first try to look up the special traversed item:
+
+  >>> from zope.testbrowser.testing import Browser
+  >>> browser = Browser()
+  >>> browser.handleErrors = False
+  >>> browser.open("http://localhost/herd/special")
+  >>> print browser.contents
+  special view
+  >>> browser.open("http://localhost/herd/special/index")
+  >>> print browser.contents
+  special view
+
+Even if we have a container item called 'special', we should still
+get our special object:
+
+  >>> herd['special'] = Mammoth('Special invisible mammoth')
+  >>> browser.open("http://localhost/herd/special")
+  >>> print browser.contents
+  special view
+  >>> browser.open("http://localhost/herd/special/index")
+  >>> print browser.contents
+  special view
+  
+The fall-back behavior should work for items that aren't traversed:
+
+  >>> browser.open("http://localhost/herd/manfred")
+  >>> print browser.contents
+  <html>
+  <body>
+  <h1>Hello, Manfred!</h1>
+  </body>
+  </html>
+
+  >>> browser.open("http://localhost/herd/ellie")
+  >>> print browser.contents
+  <html>
+  <body>
+  <h1>Hello, Ellie!</h1>
+  </body>
+  </html>
+
+"""
+import grok
+
+class Herd(grok.Container):
+    pass
+
+class Traverser(grok.Traverser):
+    grok.context(Herd)
+    def traverse(self, name):
+        if name == 'special':
+            return Special()
+        return None
+    
+class Mammoth(grok.Model):
+    def __init__(self, name):
+        self.name = name
+
+class Special(grok.Model):
+    pass
+
+class SpecialIndex(grok.View):
+    grok.context(Special)
+    grok.name('index')
+    
+    def render(self):
+        return "special view"
+
+grok.context(Mammoth)
+
+index = grok.PageTemplate("""\
+<html>
+<body>
+<h1>Hello, <span tal:replace="context/name/title" />!</h1>
+</body>
+</html>
+""")



More information about the Checkins mailing list