diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-01-27 21:57:11 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-01-27 21:57:11 +0000 |
| commit | e62e479e338e428f6cfd3b07790545982b7cb94f (patch) | |
| tree | c9784577f791d4a8ea5b80a9fce211ce86009712 /repoze/bfg/urldispatch.py | |
| parent | 2301cf61977102b85279ea7c04797f76012202e5 (diff) | |
| download | pyramid-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.py | 61 |
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]) |
