summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2013-08-19 22:56:54 -0500
committerMichael Merickel <michael@merickel.org>2013-08-19 23:01:49 -0500
commit84367e57afc0d5538e02f670834809933d9cab26 (patch)
treeff4bd3bd628fdf303e8a5140be29519a02fd07fb
parentc14c8d7c86bd5cad207fab9acc053dc723dd2acf (diff)
downloadpyramid-84367e57afc0d5538e02f670834809933d9cab26.tar.gz
pyramid-84367e57afc0d5538e02f670834809933d9cab26.tar.bz2
pyramid-84367e57afc0d5538e02f670834809933d9cab26.zip
allow pregenerator and route_prefix with external routes
-rw-r--r--docs/narr/urldispatch.rst5
-rw-r--r--pyramid/config/routes.py47
-rw-r--r--pyramid/tests/test_url.py41
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):