[Checkins] SVN: grok/trunk/src/grok/ Fix
https://bugs.launchpad.net/grok/+bug/125735:
Philipp von Weitershausen
philikon at philikon.de
Sat Jul 14 09:00:42 EDT 2007
Log message for revision 77924:
Fix https://bugs.launchpad.net/grok/+bug/125735:
When a custom traverser returns an object that doesn't have a __parent__ (and
__name__) attribute yet, it should be set automatically.
Changed:
U grok/trunk/src/grok/components.py
U grok/trunk/src/grok/ftests/traversal/modeltraverse.py
U grok/trunk/src/grok/ftests/traversal/traverser.py
A grok/trunk/src/grok/ftests/traversal/traverser_sets_parent.py
U grok/trunk/src/grok/util.py
-=-
Modified: grok/trunk/src/grok/components.py
===================================================================
--- grok/trunk/src/grok/components.py 2007-07-14 12:31:54 UTC (rev 77923)
+++ grok/trunk/src/grok/components.py 2007-07-14 13:00:42 UTC (rev 77924)
@@ -1,6 +1,6 @@
##############################################################################
#
-# Copyright (c) 2006â2007 Zope Corporation and Contributors.
+# Copyright (c) 2006-2007 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
@@ -49,12 +49,10 @@
from zope.app.container.interfaces import IReadContainer
from zope.app.component.site import SiteManagerContainer
-from martian import util
+import martian.util
+from grok import interfaces, formlib, util
-from grok import interfaces, formlib
-from grok.util import url
-
class Model(Contained, persistent.Persistent):
# XXX Inheritance order is important here. If we reverse this,
# then containers can't be models anymore because no unambigous MRO
@@ -154,7 +152,7 @@
elif name is not None and obj is None:
# create URL to view on context
obj = self.context
- return url(self.request, obj, name)
+ return util.url(self.request, obj, name)
def application_url(self, name=None):
obj = self.context
@@ -208,7 +206,7 @@
def __init__(self, template):
super(PageTemplate, self).__init__()
- if util.not_unicode_or_ascii(template):
+ if martian.util.not_unicode_or_ascii(template):
raise ValueError("Invalid page template. Page templates must be "
"unicode or ASCII.")
self.write(template)
@@ -217,7 +215,7 @@
# inline templates
# XXX unfortunately using caller_module means that
# PageTemplate cannot be subclassed
- self.__grok_module__ = util.caller_module()
+ self.__grok_module__ = martian.util.caller_module()
class PageTemplateFile(GrokPageTemplate, TrustedAppPT,
@@ -231,7 +229,7 @@
# inline templates
# XXX unfortunately using caller_module means that
# PageTemplateFile cannot be subclassed
- self.__grok_module__ = util.caller_module()
+ self.__grok_module__ = martian.util.caller_module()
class DirectoryResource(directoryresource.DirectoryResource):
@@ -277,7 +275,7 @@
def publishTraverse(self, request, name):
subob = self.traverse(name)
if subob is not None:
- return subob
+ return util.safely_locate_maybe(subob, self.context, name)
# 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
@@ -471,6 +469,6 @@
self.__grok_indexes__ = indexes
# __grok_module__ is needed to make defined_locally() return True for
# inline templates
- self.__grok_module__ = util.caller_module()
+ self.__grok_module__ = martian.util.caller_module()
Indexes = IndexesClass('Indexes')
Modified: grok/trunk/src/grok/ftests/traversal/modeltraverse.py
===================================================================
--- grok/trunk/src/grok/ftests/traversal/modeltraverse.py 2007-07-14 12:31:54 UTC (rev 77923)
+++ grok/trunk/src/grok/ftests/traversal/modeltraverse.py 2007-07-14 13:00:42 UTC (rev 77924)
@@ -5,7 +5,7 @@
>>> import grok
>>> from grok.ftests.traversal.modeltraverse import Herd
>>> grok.grok('grok.ftests.traversal.modeltraverse')
- >>> getRootFolder()["herd"] = Herd()
+ >>> getRootFolder()["herd"] = Herd('The Big Mammoth Herd')
>>> from zope.testbrowser.testing import Browser
>>> browser = Browser()
@@ -15,6 +15,7 @@
<html>
<body>
<h1>Hello, Manfred!</h1>
+ <p>Manfred is part of The Big Mammoth Herd.</p>
</body>
</html>
@@ -23,6 +24,7 @@
<html>
<body>
<h1>Hello, Ellie!</h1>
+ <p>Ellie is part of The Big Mammoth Herd.</p>
</body>
</html>
@@ -31,6 +33,9 @@
class Herd(grok.Model):
+ def __init__(self, name):
+ self.name = name
+
def getMammoth(self, name):
return Mammoth(name)
@@ -51,6 +56,7 @@
<html>
<body>
<h1>Hello, <span tal:replace="context/name/title" />!</h1>
+<p><span tal:replace="context/name/title" /> is part of <span tal:replace="context/__parent__/name" />.</p>
</body>
</html>
""")
Modified: grok/trunk/src/grok/ftests/traversal/traverser.py
===================================================================
--- grok/trunk/src/grok/ftests/traversal/traverser.py 2007-07-14 12:31:54 UTC (rev 77923)
+++ grok/trunk/src/grok/ftests/traversal/traverser.py 2007-07-14 13:00:42 UTC (rev 77924)
@@ -5,7 +5,7 @@
>>> import grok
>>> from grok.ftests.traversal.traverser import Herd
>>> grok.grok('grok.ftests.traversal.traverser')
- >>> getRootFolder()["herd"] = Herd()
+ >>> getRootFolder()["herd"] = Herd('The Big Mammoth Herd')
>>> from zope.testbrowser.testing import Browser
>>> browser = Browser()
@@ -15,6 +15,7 @@
<html>
<body>
<h1>Hello, Manfred!</h1>
+ <p>Manfred is part of The Big Mammoth Herd.</p>
</body>
</html>
@@ -23,6 +24,7 @@
<html>
<body>
<h1>Hello, Ellie!</h1>
+ <p>Ellie is part of The Big Mammoth Herd.</p>
</body>
</html>
@@ -30,8 +32,10 @@
import grok
class Herd(grok.Model):
- pass
+ def __init__(self, name):
+ self.name = name
+
class HerdTraverser(grok.Traverser):
grok.context(Herd)
@@ -52,6 +56,7 @@
<html>
<body>
<h1>Hello, <span tal:replace="context/name/title" />!</h1>
+<p><span tal:replace="context/name/title" /> is part of <span tal:replace="context/__parent__/name" />.</p>
</body>
</html>
""")
Added: grok/trunk/src/grok/ftests/traversal/traverser_sets_parent.py
===================================================================
--- grok/trunk/src/grok/ftests/traversal/traverser_sets_parent.py (rev 0)
+++ grok/trunk/src/grok/ftests/traversal/traverser_sets_parent.py 2007-07-14 13:00:42 UTC (rev 77924)
@@ -0,0 +1,66 @@
+"""
+A traverser can set the __parent__ (and __name__) attributes itself,
+in which case Grok's traverser won't interfere:
+
+ >>> import grok
+ >>> from grok.ftests.traversal.traverser_sets_parent import Herd
+ >>> grok.grok('grok.ftests.traversal.traverser_sets_parent')
+ >>> getRootFolder()["herd"] = Herd('The Big Mammoth Herd')
+
+ >>> from zope.testbrowser.testing import Browser
+ >>> browser = Browser()
+ >>> browser.handleErrors = False
+ >>> browser.open("http://localhost/herd/manfred")
+ >>> print browser.contents
+ <html>
+ <body>
+ <h1>Hello, Manfred!</h1>
+ <p>Manfred is part of The Three Stooges.</p>
+ </body>
+ </html>
+
+ >>> browser.open("http://localhost/herd/ellie")
+ >>> print browser.contents
+ <html>
+ <body>
+ <h1>Hello, Ellie!</h1>
+ <p>Ellie is part of The Three Stooges.</p>
+ </body>
+ </html>
+
+"""
+import grok
+
+class Herd(grok.Model):
+
+ def __init__(self, name):
+ self.name = name
+
+class HerdTraverser(grok.Traverser):
+ grok.context(Herd)
+
+ def traverse(self, name):
+ mammoth = Mammoth(name)
+ # We pretend the mammoth is the child object of some competely
+ # differnt Herd object.
+ mammoth.__parent__ = Herd('The Three Stooges')
+ return mammoth
+
+class Mammoth(grok.Model):
+
+ def __init__(self, name):
+ self.name = name
+
+grok.context(Mammoth)
+
+class Index(grok.View):
+ pass
+
+index = grok.PageTemplate("""\
+<html>
+<body>
+<h1>Hello, <span tal:replace="context/name/title" />!</h1>
+<p><span tal:replace="context/name/title" /> is part of <span tal:replace="context/__parent__/name" />.</p>
+</body>
+</html>
+""")
Property changes on: grok/trunk/src/grok/ftests/traversal/traverser_sets_parent.py
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: grok/trunk/src/grok/util.py
===================================================================
--- grok/trunk/src/grok/util.py 2007-07-14 12:31:54 UTC (rev 77923)
+++ grok/trunk/src/grok/util.py 2007-07-14 13:00:42 UTC (rev 77924)
@@ -16,6 +16,7 @@
import urllib
+import zope.location.interfaces
from zope import component
from zope.traversing.browser.interfaces import IAbsoluteURL
from zope.traversing.browser.absoluteurl import _safe as SAFE_URL_CHARACTERS
@@ -84,3 +85,17 @@
return url
return url + '/' + urllib.quote(name.encode('utf-8'),
SAFE_URL_CHARACTERS)
+
+def safely_locate_maybe(obj, parent, name):
+ """Set an object's __parent__ (and __name__) if the object's
+ __parent__ attribute doesn't exist yet or is None.
+
+ If the object provides ILocation, __parent__ and __name__ will be
+ set directly. A location proxy will be returned otherwise.
+ """
+ if getattr(obj, '__parent__', None) is not None:
+ return obj
+ if zope.location.interfaces.ILocation.providedBy(obj):
+ zope.location.locate(obj, parent, name)
+ return obj
+ return zope.location.LocationProxy(obj, parent, name)
More information about the Checkins
mailing list