diff options
| author | Michael Merickel <michael@merickel.org> | 2013-08-19 22:56:54 -0500 |
|---|---|---|
| committer | Michael Merickel <michael@merickel.org> | 2013-08-19 23:01:49 -0500 |
| commit | 84367e57afc0d5538e02f670834809933d9cab26 (patch) | |
| tree | ff4bd3bd628fdf303e8a5140be29519a02fd07fb | |
| parent | c14c8d7c86bd5cad207fab9acc053dc723dd2acf (diff) | |
| download | pyramid-84367e57afc0d5538e02f670834809933d9cab26.tar.gz pyramid-84367e57afc0d5538e02f670834809933d9cab26.tar.bz2 pyramid-84367e57afc0d5538e02f670834809933d9cab26.zip | |
allow pregenerator and route_prefix with external routes
| -rw-r--r-- | docs/narr/urldispatch.rst | 5 | ||||
| -rw-r--r-- | pyramid/config/routes.py | 47 | ||||
| -rw-r--r-- | pyramid/tests/test_url.py | 41 |
3 files changed, 57 insertions, 36 deletions
diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 8f03b1080..f3513624e 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -790,11 +790,6 @@ All pattern replacements and calls to :meth:`pyramid.request.Request.route_path` will also just return the external URLs path part. -.. note:: - - The external URL feature is implemented with a :term:`pregenerator` so you - cannot use both with the same route. - .. index:: single: redirecting to slash-appended routes diff --git a/pyramid/config/routes.py b/pyramid/config/routes.py index 0e11428db..af7ddd6f3 100644 --- a/pyramid/config/routes.py +++ b/pyramid/config/routes.py @@ -1,6 +1,6 @@ import warnings -from urlparse import urlparse +from pyramid.compat import urlparse from pyramid.interfaces import ( IRequest, IRouteRequest, @@ -385,28 +385,33 @@ class RoutesConfiguratorMixin(object): if pattern is None: raise ConfigurationError('"pattern" argument may not be None') - if self.route_prefix: + # check for an external route + parsed = urlparse.urlparse(pattern) + if parsed.hostname: + pattern = parsed.path + + original_pregenerator = pregenerator + def external_url_pregenerator(request, elements, kw): + if '_app_url' not in kw: + if '_scheme' in kw: + scheme = kw['_scheme'] + elif parsed.scheme: + scheme = parsed.scheme + else: + scheme = request.scheme + kw['_app_url'] = '{0}://{1}'.format(scheme, parsed.netloc) + + if original_pregenerator: + elements, kw = original_pregenerator( + request, elements, kw) + return elements, kw + + pregenerator = external_url_pregenerator + static = True + + elif self.route_prefix: pattern = self.route_prefix.rstrip('/') + '/' + pattern.lstrip('/') - if pregenerator is None: - parsed = urlparse(pattern) - if parsed.hostname: - pattern = parsed.path - - def external_url_pregenerator(request, elements, kw): - if not '_app_url' in kw: - if '_scheme' in kw and parsed.scheme != kw['_scheme']: - scheme = kw['_scheme'] - elif parsed.scheme: - scheme = parsed.scheme - else: - scheme = request.scheme - kw['_app_url'] = '{0}://{1}'.format( - scheme, parsed.netloc) - return elements, kw - - pregenerator = external_url_pregenerator - mapper = self.get_routes_mapper() introspectables = [] diff --git a/pyramid/tests/test_url.py b/pyramid/tests/test_url.py index 0e006f447..9e4f72c41 100644 --- a/pyramid/tests/test_url.py +++ b/pyramid/tests/test_url.py @@ -1036,47 +1036,68 @@ class Test_external_static_url_integration(unittest.TestCase): testing.tearDown() def _makeRequest(self): - from pyramid.request import Request + from pyramid.request import Request return Request.blank('/') def test_generate_external_url(self): self.config.add_route('acme', 'https://acme.org/path/{foo}') request = self._makeRequest() request.registry = self.config.registry - self.assertEqual(request.route_url('acme', foo='bar'), + self.assertEqual( + request.route_url('acme', foo='bar'), 'https://acme.org/path/bar') def test_generate_external_url_without_scheme(self): self.config.add_route('acme', '//acme.org/path/{foo}') request = self._makeRequest() request.registry = self.config.registry - self.assertEqual(request.route_url('acme', foo='bar'), + self.assertEqual( + request.route_url('acme', foo='bar'), 'http://acme.org/path/bar') - def test_generate_external_url_with_explicit_scheme(self): self.config.add_route('acme', '//acme.org/path/{foo}') request = self._makeRequest() request.registry = self.config.registry - self.assertEqual(request.route_url('acme', foo='bar', _scheme='https'), + self.assertEqual( + request.route_url('acme', foo='bar', _scheme='https'), 'https://acme.org/path/bar') - def test_generate_external_url_with_explicit_app_url(self): self.config.add_route('acme', 'http://acme.org/path/{foo}') request = self._makeRequest() request.registry = self.config.registry - self.assertEqual(request.route_url('acme', foo='bar', _app_url='http://fakeme.com'), + self.assertEqual( + request.route_url('acme', foo='bar', _app_url='http://fakeme.com'), 'http://fakeme.com/path/bar') - def test_generate_external_url_route_path(self): self.config.add_route('acme', 'https://acme.org/path/{foo}') request = self._makeRequest() request.registry = self.config.registry - self.assertEqual(request.route_path('acme', foo='bar'), - '/path/bar') + self.assertEqual(request.route_path('acme', foo='bar'), '/path/bar') + def test_generate_external_url_with_pregenerator(self): + def pregenerator(request, elements, kw): + kw['_query'] = {'q': 'foo'} + return elements, kw + self.config.add_route('acme', 'https://acme.org/path/{foo}', + pregenerator=pregenerator) + request = self._makeRequest() + request.registry = self.config.registry + self.assertEqual( + request.route_url('acme', foo='bar'), + 'https://acme.org/path/bar?q=foo') + + def test_external_url_with_route_prefix(self): + def includeme(config): + config.add_route('acme', '//acme.org/{foo}') + self.config.include(includeme, route_prefix='some_prefix') + request = self._makeRequest() + request.registry = self.config.registry + self.assertEqual( + request.route_url('acme', foo='bar'), + 'http://acme.org/bar') class DummyContext(object): def __init__(self, next=None): |
