diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-05-16 18:48:02 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-05-16 18:48:02 +0000 |
| commit | 29e01279ff0b13623a6b1b769351632f12bafb35 (patch) | |
| tree | b53e44b99df1f4fdf5f3437e7228b53652e53fc0 /repoze/bfg/urldispatch.py | |
| parent | dfad1fbd9fa46c67aee8de3c3d3b36c0af1ec7bf (diff) | |
| download | pyramid-29e01279ff0b13623a6b1b769351632f12bafb35.tar.gz pyramid-29e01279ff0b13623a6b1b769351632f12bafb35.tar.bz2 pyramid-29e01279ff0b13623a6b1b769351632f12bafb35.zip | |
- The ``RoutesMapper`` class in ``repoze.bfg.urldispatch`` has been
removed, as well as its documentation. It had been deprecated since
0.6.3. Code in ``repoze.bfg.urldispatch.RoutesModelTraverser``
which catered to it has also been removed.
- The semantics of the ``route`` ZCML directive have been simplified.
Previously, it was assumed that to use a route, you wanted to map a
route to an externally registered view. The new ``route`` directive
instead has a ``view`` attribute which is required, specifying the
dotted path to a view callable. When a route directive is
processed, a view is *registered* using the name attribute of the
route directive as its name and the callable as its value. The
``view_name`` and ``provides`` attributes of the ``route`` directive
are therefore no longer used. Effectively, if you were previously
using the ``route`` directive, it means you must change a pair of
ZCML directives that look like this::
<route
name="home"
path=""
view_name="login"
factory=".models.root.Root"
/>
<view
for=".models.root.Root"
name="login"
view=".views.login_view"
/>
To a ZCML directive that looks like this::
<route
name="home"
path=""
view=".views.login_view"
factory=".models.root.Root"
/>
In other words, to make old code work, remove the ``view``
directives that were only there to serve the purpose of backing
``route`` directives, and move their ``view=`` attribute into the
``route`` directive itself.
This change also necessitated that the ``name`` attribute of the
``route`` directive is now required. If you were previously using
``route`` directives without a ``name`` attribute, you'll need to
add one (the name is arbitrary, but must be unique among all
``route`` and ``view`` statements).
The ``provides`` attribute of the ``route`` directive has also been
removed. This directive specified a sequence of interface types
that the generated context would be decorated with. Since route
views are always generated now for a single interface
(``repoze.bfg.IRoutesContext``) as opposed to being looked up
arbitrarily, there is no need to decorate any context to ensure a
view is found.
- The Routes ``Route`` object used to resolve the match is now put
into the environment as ``bfg.route`` when URL dispatch is used.
Diffstat (limited to 'repoze/bfg/urldispatch.py')
| -rw-r--r-- | repoze/bfg/urldispatch.py | 114 |
1 files changed, 8 insertions, 106 deletions
diff --git a/repoze/bfg/urldispatch.py b/repoze/bfg/urldispatch.py index ead8876de..2b6717891 100644 --- a/repoze/bfg/urldispatch.py +++ b/repoze/bfg/urldispatch.py @@ -31,85 +31,6 @@ deprecated('RoutesContext', "DefaultRoutesContext')", ) -class RoutesMapper(object): - """ The ``RoutesMapper`` is a wrapper for the ``get_root`` - callable passed in to the repoze.bfg ``Router`` at initialization - time. When it is instantiated, it wraps the get_root of an - application in such a way that the `Routes - <http://routes.groovie.org/index.html>`_ engine has the 'first - crack' at resolving the current request URL to a repoze.bfg view. - Any view that claims it is 'for' the interface - ``repoze.bfg.interfaces.IRoutesContext`` will be called if its - *name* matches the Routes 'controller' name for the match. It - will be passed a context object that has attributes that match the - Routes match arguments dictionary keys. If no Routes route - matches the current request, the 'fallback' get_root is called. - - .. warning:: This class is deprecated. As of :mod:`repoze.bfg` - 0.6.3, you should use the ``<route.. >`` ZCML directive instead - of manually creating a RoutesMapper. See :ref:`urldispatch_chapter` - for more information. - """ - def __init__(self, get_root): - self.get_root = get_root - self.mapper = Mapper(controller_scan=None, directory=None, - explicit=True, always_scan=False) - self.mapper.explicit = True - self._regs_created = False - - def __call__(self, environ): - if not self._regs_created: - self.mapper.create_regs([]) - self._regs_created = True - path = environ.get('PATH_INFO', '/') - self.mapper.environ = environ - args = self.mapper.match(path) - if isinstance(args, dict): # might be an empty dict - context_factory = args.get('context_factory', _marker) - if context_factory is _marker: - context_factory = DefaultRoutesContext - else: - args = args.copy() - del args['context_factory'] - config = request_config() - config.mapper = self.mapper - config.mapper_dict = args - config.host = environ.get('HTTP_HOST', environ['SERVER_NAME']) - config.protocol = environ['wsgi.url_scheme'] - config.redirect = None - context = context_factory(**args) - alsoProvides(context, IRoutesContext) - return context - - # fall back to original get_root - return self.get_root(environ) - - def connect(self, *arg, **kw): - """ Add a route to the Routes mapper associated with this - request. This method accepts the same arguments as a Routes - *Mapper* object. One differences exists: if the - ``context_factory`` is passed in with a value as a keyword - argument, this callable will be called when a model object - representing the ``context`` for the request needs to be - constructed. It will be called with the (all-keyword) - arguments supplied by the Routes mapper's ``match`` method for - this route, and should return an instance of a class. If - ``context_factory`` is not supplied in this way for a route, a - default context factory (the ``DefaultRoutesContext`` class) - will be used. The interface - ``repoze.bfg.interfaces.IRoutesContext`` will always be tacked - on to the context instance in addition to whatever interfaces - the context instance already supplies. - """ - - self.mapper.connect(*arg, **kw) - -deprecated('RoutesMapper', - 'Usage of the ``RoutesMapper`` class is deprecated. As of ' - 'repoze.bfg 0.6.3, you should use the ``<route.. >`` ZCML ' - 'directive instead of manually creating a RoutesMapper.', - ) - class RoutesContextNotFound(object): implements(IContextNotFound) def __init__(self, msg): @@ -172,7 +93,7 @@ class RoutesRootFactory(Mapper): args = args.copy() routepath = route.routepath factory = route._factory - if not factory: + if factory is None: factory = DefaultRoutesContext config = request_config() config.mapper = self @@ -189,9 +110,7 @@ class RoutesRootFactory(Mapper): kw[k] = v context = factory(**kw) environ['wsgiorg.routing_args'] = ((), kw) - provides = route._provides - for iface in provides: - alsoProvides(context, iface) + environ['bfg.route'] = route alsoProvides(context, IRoutesContext) return context @@ -207,29 +126,12 @@ class RoutesModelTraverser(object): 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 + - match = environ['wsgiorg.routing_args'][1] - except KeyError: - # <= 0.6.4 - match = self.context.__dict__ - try: - view_name = match['view_name'] - except KeyError: - # b/w compat < 0.6.3 - try: - view_name = match['controller'] - except KeyError: - view_name = '' - try: - subpath = match['subpath'] + route = environ['bfg.route'] + match = environ['wsgiorg.routing_args'][1] + + subpath = match.get('subpath', []) + if subpath: subpath = filter(None, subpath.split('/')) - except KeyError: - # b/w compat < 0.6.5 - subpath = [] if 'path_info' in match: # this is stolen from routes.middleware; if the route map @@ -245,7 +147,7 @@ class RoutesModelTraverser(object): if environ['SCRIPT_NAME'].endswith('/'): environ['SCRIPT_NAME'] = environ['SCRIPT_NAME'][:-1] - return self.context, view_name, subpath, None, self.context, None + return self.context, route.name, subpath, None, self.context, None class RoutesContextURL(object): """ The IContextURL adapter used to generate URLs for a context |
