Skip to content

Instantly share code, notes, and snippets.

@freeekanayaka
Created February 8, 2012 20:15
Show Gist options
  • Save freeekanayaka/1772990 to your computer and use it in GitHub Desktop.
Save freeekanayaka/1772990 to your computer and use it in GitHub Desktop.
Context routes spike
import sys
from zope.interface import Interface, implementer
from pyramid.interfaces import ITraverser
from pyramid.urldispatch import Route
from pyramid.traversal import traversal_path_info
ROUTES_ATTRS = "__routes__"
class IContextRoutes(Interface):
pass
@implementer(IContextRoutes)
class ContextRoutes(object):
def __init__(self, context, request):
self.context = context
self.request = request
def __call__(self, path):
for route in self.__routes__:
match = route.match(path)
if match is not None:
# XXX have route not turn traverse into a tuple
return {"traverse": "/".join(match.pop("traverse")),
"context": getattr(self, route.name)(**match)}
def route(pattern):
pattern += "*traverse"
frame = sys._getframe(1)
locals = frame.f_locals
routes = locals.get(ROUTES_ATTRS)
if not routes:
locals[ROUTES_ATTRS] = routes = []
def wrapper(method):
routes.append(Route(method.__name__, pattern))
return method
return wrapper
@implementer(ITraverser)
class ContextRoutesTraverser(object):
def __init__(self, root):
self.root = root
def __call__(self, request):
environ = request.environ
registry = request.registry
try:
path = environ['PATH_INFO'] or '/'
except KeyError:
path = '/'
context = self.root
traverse = path
while traverse != "/":
routes = registry.queryMultiAdapter((context, request),
IContextRoutes)
if routes is None:
break
info = routes(traverse)
if info is None:
break
next_traverse, context = info["traverse"], info["context"]
if not len(next_traverse) < len(traverse):
raise RuntimeError() # XXX Test this
traverse = "/" + next_traverse
subpath = traversal_path_info(traverse)
if traverse == "/":
traversed = path
else:
traversed = path[:-(len(traverse) - 1)]
traversed = traversal_path_info(traversed)
return {"context": context,
"view_name": "" if not subpath else subpath[0],
"subpath": subpath,
"traversed": traversed,
"virtual_root": self.root,
"virtual_root_path": path,
"root": self.root}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment