[Zope-Checkins] CVS: Zope/lib/python/ZPublisher - BaseRequest.py:1.39.20.6
Shane Hathaway
shane@digicool.com
Thu, 25 Oct 2001 16:39:35 -0400
Update of /cvs-repository/Zope/lib/python/ZPublisher
In directory cvs.zope.org:/tmp/cvs-serv16082
Modified Files:
Tag: ComponentArchitecture-branch
BaseRequest.py
Log Message:
Added DefaultBrowserPublish and cleaned up traverse() some more.
Also added _browser_renderable() but this will need review.
=== Zope/lib/python/ZPublisher/BaseRequest.py 1.39.20.5 => 1.39.20.6 ===
from urllib import quote
from cgi import escape
+from types import StringType
UNSPECIFIED_ROLES=''
@@ -277,37 +278,39 @@
return object, roles
def _finalTraverse(self, object):
+ if hasattr(object, '_browser_renderable'):
+ object = object._browser_renderable()
roles = UNSPECIFIED_ROLES
if (hasattr(object, '__call__') and
hasattr(object.__call__,'__roles__')):
roles=object.__call__.__roles__
return object, roles
- def _addDefaultView(self, object, path, m_name='_browser_default'):
+ def _getDefaultView(self, object, m_name='_browser_default'):
"""
- returns (object, entry_name)
+ returns (object, add_steps)
"""
psteps = None
- default = getattr(object, m_name, None)
- if default is not None:
- o, add_steps = default(self)
- if add_steps:
- if len(add_steps) > 1:
- # 2 or more steps added
- path.extend(add_steps[1:])
- # 1 step added
- return o, add_steps[0]
- elif o is not object:
- # no steps added but object changed.
- return o, ()
+ f = getattr(object, m_name, None)
+ if f is not None:
+ v = f(self)
+ if v is not None:
+ if type(v) is StringType:
+ # One more traversal step.
+ return o, (v,)
+ else:
+ # Arbitrary additional traversal.
+ o, add_steps = v
+ if add_steps or o is not object:
+ return o, add_steps
m = self._request_method
if m == 'GET' or m == 'POST':
default = 'index_html'
else:
default = m
if default and getattr(object, default, None) is not None:
- return object, default
- return object, None
+ return object, (default,)
+ return object, ()
def _traverseName(self, object, entry_name, m_name="__bobo_traverse__"):
"""
@@ -450,14 +453,13 @@
The REQUEST must already have a PARENTS item with at least one
object in it. This is typically the root object.
"""
- request = self
checked_default = 0
path = self._splitPath(path_str)
self._setRequestMethod()
if not path and not self._request_method:
return self.response.forbiddenError(self['URL'])
- parents=request['PARENTS']
+ parents=self['PARENTS']
object=parents[-1]
del parents[:]
object, roles = self._initialTraverse(object)
@@ -466,54 +468,62 @@
steps=self.steps
self._steps = _steps = map(quote, steps)
path.reverse()
- request['TraversalRequestNameStack'] = request.path = path
+ self['TraversalRequestNameStack'] = self.path = path
- entry_name = ''
+ prev_object = None
try:
# We build parents in the wrong order, so we
# need to make sure we reverse it when we're doe.
while 1:
- hook = getattr(object, '__before_publishing_traverse__', None)
- if hook is not None:
- hook(object, self)
+ if object is not prev_object: # Don't call hooks twice
+ hook = getattr(
+ object, '__before_publishing_traverse__', None)
+ if hook is not None:
+ hook(object, self)
+ prev_object = object
- path = self.path = self['TraversalRequestNameStack']
+ self.path = path = self['TraversalRequestNameStack']
if path:
+ # Traverse to the next step.
entry_name = path.pop()
+ if entry_name:
+ step = quote(entry_name)
+ _steps.append(step)
+ self['URL'] = '%s/%s' % (self['URL'], step)
+ try:
+ object, r = self._traverseName(object, entry_name)
+ if r is not UNSPECIFIED_ROLES:
+ roles = r
+ except StopTraversal, v:
+ return v
+ parents.append(object)
+ steps.append(entry_name)
+
+ elif not checked_default:
+ # Traverse to the default view, if any.
+ checked_default = 1
+ object, add_steps = self._getDefaultView(object)
+ if add_steps:
+ path.extend(add_steps)
+ self._hacked_path = 1
+
else:
- entry_name = None
- if not checked_default:
- object, entry_name = self._addDefaultView(object, path)
- checked_default = 1
- if entry_name:
- self._hacked_path = 1
- if not entry_name:
- # Finished traversal.
- object, r = self._finalTraverse(object)
- if r is not UNSPECIFIED_ROLES:
- roles = r
- if self._hacked_path:
- URL = self['URL']
- i=rfind(URL,'/')
- if i > 0: self.response.setBase(URL[:i])
- break
- if not entry_name:
- continue
- step = quote(entry_name)
- _steps.append(step)
- request['URL'] = '%s/%s' % (request['URL'], step)
- try:
- object, r = self._traverseName(object, entry_name)
- if r is not UNSPECIFIED_ROLES:
- roles = r
- except StopTraversal, v:
- return v
- parents.append(object)
- steps.append(entry_name)
+ # Finished traversal.
+ break
+
+ object, r = self._finalTraverse(object)
+ if r is not UNSPECIFIED_ROLES:
+ roles = r
+ if self._hacked_path:
+ URL = self['URL']
+ i = rfind(URL,'/')
+ if i > 0:
+ self.response.setBase(URL[:i])
+
finally:
parents.reverse()
- request['PUBLISHED'] = parents.pop(0)
+ self['PUBLISHED'] = object
# Do authorization checks
self._checkAuthorization(object, parents, roles, validated_hook)