summaryrefslogtreecommitdiff
path: root/repoze/bfg/urldispatch.py
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-01-27 21:57:11 +0000
committerChris McDonough <chrism@agendaless.com>2009-01-27 21:57:11 +0000
commite62e479e338e428f6cfd3b07790545982b7cb94f (patch)
treec9784577f791d4a8ea5b80a9fce211ce86009712 /repoze/bfg/urldispatch.py
parent2301cf61977102b85279ea7c04797f76012202e5 (diff)
downloadpyramid-e62e479e338e428f6cfd3b07790545982b7cb94f.tar.gz
pyramid-e62e479e338e428f6cfd3b07790545982b7cb94f.tar.bz2
pyramid-e62e479e338e428f6cfd3b07790545982b7cb94f.zip
Features
-------- - The ``repoze.bfg.url.model_url`` API now works against contexts derived from Routes URL dispatch (``Routes.util.url_for`` is called under the hood). - "Virtual root" support for traversal-based applications has been added. Virtual root support is useful when you'd like to host some model in a :mod:`repoze.bfg` model graph as an application under a URL pathname that does not include the model path itself. For more information, see the (new) "Virtual Hosting" chapter in the documentation. - A ``repoze.bfg.traversal.virtual_root`` API has been added. When called, it returns the virtual root object (or the physical root object if no virtual root has been specified). Implementation Changes ---------------------- - ``repoze.bfg.traversal.RoutesModelTraverser`` has been moved to ``repoze.bfg.urldispatch``. - ``model_url`` URL generation is now performed via an adapter lookup based on the context and the request. - ZCML which registers two adapters for the ``IContextURL`` interface has been added to the configure.zcml in ``repoze.bfg.includes``.
Diffstat (limited to 'repoze/bfg/urldispatch.py')
-rw-r--r--repoze/bfg/urldispatch.py61
1 files changed, 60 insertions, 1 deletions
diff --git a/repoze/bfg/urldispatch.py b/repoze/bfg/urldispatch.py
index 0c71c6e74..03b73d6c6 100644
--- a/repoze/bfg/urldispatch.py
+++ b/repoze/bfg/urldispatch.py
@@ -1,11 +1,17 @@
from zope.interface import implements
from zope.interface import alsoProvides
+from zope.interface import classProvides
+
from routes import Mapper
from routes import request_config
+from routes import url_for
-from repoze.bfg.interfaces import IRoutesContext
from repoze.bfg.interfaces import IContextNotFound
+from repoze.bfg.interfaces import IContextURL
+from repoze.bfg.interfaces import IRoutesContext
+from repoze.bfg.interfaces import ITraverser
+from repoze.bfg.interfaces import ITraverserFactory
from zope.deferredimport import deprecated
from zope.deprecation import deprecated as deprecated2
@@ -191,3 +197,56 @@ class RoutesRootFactory(Mapper):
# fall back to original get_root
return self.get_root(environ)
+
+class RoutesModelTraverser(object):
+ classProvides(ITraverserFactory)
+ implements(ITraverser)
+ def __init__(self, context):
+ self.context = context
+
+ def __call__(self, environ):
+ # the traverser *wants* to get routing args from the environ
+ # as of 0.6.5; the rest of this stuff is for backwards
+ # compatibility
+ try:
+ # 0.6.5 +
+ routing_args = environ['wsgiorg.routing_args'][1]
+ except KeyError:
+ # <= 0.6.4
+ routing_args = self.context.__dict__
+ try:
+ view_name = routing_args['view_name']
+ except KeyError:
+ # b/w compat < 0.6.3
+ try:
+ view_name = routing_args['controller']
+ except KeyError:
+ view_name = ''
+ try:
+ subpath = routing_args['subpath']
+ subpath = filter(None, subpath.split('/'))
+ except KeyError:
+ # b/w compat < 0.6.5
+ subpath = []
+
+ return self.context, view_name, subpath
+
+class RoutesContextURL(object):
+ """ The IContextURL adapter used to generate URLs for a context
+ object obtained via Routes URL dispatch. This implementation
+ juses the ``url_for`` Routes API to generate a URL based on
+ ``environ['wsgiorg.routing_args']``. Routes context objects,
+ unlike traversal-based context objects, cannot have a virtual root
+ that differs from its physical root; furthermore, the physical
+ root of a Routes context is always itself, so the ``virtual_root``
+ function returns the context of this adapter unconditionally."""
+ implements(IContextURL)
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ def virtual_root(self):
+ return self.context
+
+ def __call__(self):
+ return url_for(**self.request.environ['wsgiorg.routing_args'][1])