# Zope 3 imports from zope.interface import implements from zope.app import zapi from zope.app.traversing.adapters import Traverser, _marker from zope.publisher.interfaces.browser import IBrowserRequest from zope.component import ComponentLookupError # Five imports from Products.Five.traversable import FiveTraversable, FakeRequest # Product imports from topic import Topic, AuthorsTopic class SubpathTraverser(Traverser): def traverse(self, path, default=_marker, request=None): clear_name_stack = False # path looks like ['topics'], or similar... if path[0] in ['topics', 'authors']: clear_name_stack = True path = path + request['TraversalRequestNameStack'] obj = super(SubpathTraverser, self).traverse(path, default, request) if clear_name_stack: request['TraversalRequestNameStack'][:] = [] return obj class WeblogTraversable(FiveTraversable): """Intercepts traversal for IWeblogs, but only for 'topics'. Everything else is left untouched. """ def traverse(self, name, furtherPath): # Alias _subject to context for consistency with other adapter code self.context = self._subject # Only intercept certain names... if name == 'topics': topic_class = Topic elif name == 'authors': topic_class = AuthorsTopic else: # We ignore it and do default traversing. return super(WeblogTraversable, self).traverse(name, furtherPath) # Now the guts of it... # Empty furtherPath so no more traversal happens after us. subpath = self.popFurtherPath(furtherPath) # Find the REQUEST REQUEST = getattr(self.context, 'REQUEST', None) view_name = name if len(subpath) == 0: # No subpath to eat, so just lookup the 'name' view for context return zapi.getView(self.context, view_name, REQUEST) elif subpath[-1].startswith('@@'): # A view has explicitly been requested, so make that the # view_name (stripping off the leading @@ which causes view # lookups to fail otherwise). view_name = subpath[-1][2:] # Use the rest of the subpath as the keywords for the topic. topic = topic_class(subpath[:-1]).__of__(self.context) else: # No @@view given, so just lookup the default view. view_name = 'index.html' # Use all of the subpath as the keywords for the topic. topic = topic_class(subpath).__of__(self.context) # Lookup the view for the topic and return it for publishing. return zapi.getView(topic, view_name, REQUEST) def popFurtherPath(self, furtherPath): """Empty the furtherPath sequence into a new list. """ subpath = [] subpath.extend(furtherPath) while furtherPath: furtherPath.pop() return subpath