diff options
| author | Chris McDonough <chrism@agendaless.com> | 2008-07-22 11:02:28 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2008-07-22 11:02:28 +0000 |
| commit | 8392d7094c96f777f6d1d5f0c62051702191d106 (patch) | |
| tree | 6fd39e2c10fc33a5b2be08e7467c9e6ad0887b78 /repoze/bfg/urldispatch.py | |
| parent | b584143b2c408b979c340939f48b8a4ffe725e62 (diff) | |
| download | pyramid-8392d7094c96f777f6d1d5f0c62051702191d106.tar.gz pyramid-8392d7094c96f777f6d1d5f0c62051702191d106.tar.bz2 pyramid-8392d7094c96f777f6d1d5f0c62051702191d106.zip | |
Add url-based dispatch.
Diffstat (limited to 'repoze/bfg/urldispatch.py')
| -rw-r--r-- | repoze/bfg/urldispatch.py | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/repoze/bfg/urldispatch.py b/repoze/bfg/urldispatch.py new file mode 100644 index 000000000..9bdb1e5fa --- /dev/null +++ b/repoze/bfg/urldispatch.py @@ -0,0 +1,75 @@ +from zope.interface import implements +from zope.interface import classProvides + +from routes import Mapper +from routes import request_config + +from repoze.bfg.interfaces import IURLDispatchModel +from repoze.bfg.interfaces import ITraverserFactory +from repoze.bfg.interfaces import ITraverser + +class RoutesModel(object): + implements(IURLDispatchModel) + def __init__(self, **kw): + self.__dict__.update(kw) + +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. + If the ``RoutesModelTraverser`` is configured in your + application's configure.zcml, any view that claims it is 'for' the + interface ``repoze.bfg.interfaces.IURLDispatchModel`` 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.""" + 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', '/') + args = self.mapper.match(path) + if args: + 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 + model = RoutesModel(**args) + return model + # 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""" + self.mapper.connect(*arg, **kw) + +class RoutesModelTraverser(object): + classProvides(ITraverserFactory) + implements(ITraverser) + def __init__(self, model, request): + self.model = model + self.request = request + + def __call__(self, environ): + return self.model, self.model.controller, '' + + + + + |
