diff options
| -rw-r--r-- | CHANGES.txt | 11 | ||||
| -rw-r--r-- | TODO.txt | 5 | ||||
| -rw-r--r-- | docs/api/url.rst | 2 | ||||
| -rw-r--r-- | pyramid/request.py | 43 | ||||
| -rw-r--r-- | pyramid/tests/test_request.py | 17 | ||||
| -rw-r--r-- | pyramid/tests/test_url.py | 21 | ||||
| -rw-r--r-- | pyramid/url.py | 27 |
7 files changed, 120 insertions, 6 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index fd0cead61..604f28cf4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,17 @@ Next release ============ +Features +-------- + +- Add a ``pyramid.url.route_path`` API, allowing folks to generate relative + URLs. Calling ``route_path`` is the same as calling + ``pyramid.url.route_url`` with the argument ``_app_url`` equal to the empty + string. + +- Add a ``pyramid.request.Request.route_path`` API. This is a convenience + method of the request which calls ``pyramid.url.route_url``. + Bug Fixes --------- @@ -44,8 +44,6 @@ action = '^foo$' mypackage.views.MyView.foo_GET -- Ability to use configurator as a context manager. - - Provide a response_cookies attribute on the request for rendered responses that can be used as input to response.set_cookie. @@ -79,9 +77,6 @@ - translationdir ZCML directive use of ``path_spec`` should maybe die. -- Option for route_url to omit the host and port (perhaps a different - function named ``route_path``). - - SQLAlchemy idiomatics: <RaFromBRC> mcdonc: those paster templates all look pretty good... the diff --git a/docs/api/url.rst b/docs/api/url.rst index 71987498a..8c702a3fb 100644 --- a/docs/api/url.rst +++ b/docs/api/url.rst @@ -9,6 +9,8 @@ .. autofunction:: route_url + .. autofunction:: route_path + .. autofunction:: static_url .. autofunction:: urlencode diff --git a/pyramid/request.py b/pyramid/request.py index dff70d93c..43a4a3aa2 100644 --- a/pyramid/request.py +++ b/pyramid/request.py @@ -11,6 +11,7 @@ from pyramid.decorator import reify from pyramid.url import model_url from pyramid.url import route_url from pyramid.url import static_url +from pyramid.url import route_path class TemplateContext(object): pass @@ -246,13 +247,53 @@ class Request(WebobRequest): like this:: from pyramid.url import static_url - static_url('mypackage:static/foo.css, request) + static_url('mypackage:static/foo.css', request) See :func:`pyramid.url.static_url` for more information """ return static_url(path, self, **kw) + def route_path(self, route_name, *elements, **kw): + """Generates a path (aka a 'relative URL', a URL minus the host, + scheme, and port) for a named :app:`Pyramid` + :term:`route configuration`. + + .. note:: Calling :meth:`pyramid.Request.route_path` can be used to + achieve the same result as :func:`pyramid.url.route_path`. + + This is a convenience method. The result of calling + :meth:`pyramid.request.Request.route_path` is the same as calling + :func:`pyramid.url.route_path` with an explicit ``request`` + parameter. + + This method accepts the same arguments as + :meth:`pyramid.request.Request.route_url` and performs the same duty. + It just omits the host, port, and scheme information in the return + value; only the path, query parameters, and anchor data are present + in the returned string. + + The :meth:`pyramid.request.Request.route_path` method calls the + :func:`pyramid.url.route_path` function using the Request object as + the ``request`` argument. The ``*elements`` and ``*kw`` arguments + passed to :meth:`pyramid.request.Request.route_path` are passed + through to :func:`pyramid.url.route_path` unchanged and its result is + returned. + + This call to :meth:`pyramid.request.Request.route_path`:: + + request.route_path('foobar') + + Is completely equivalent to calling :func:`pyramid.url.route_path` + like this:: + + from pyramid.url import route_path + route_path('foobar', request) + + See :func:`pyramid.url.route_path` for more information + """ + return route_path(route_name, self, *elements, **kw) + # override default WebOb "environ['adhoc_attr']" mutation behavior __getattr__ = object.__getattribute__ __setattr__ = object.__setattr__ diff --git a/pyramid/tests/test_request.py b/pyramid/tests/test_request.py index a398bf3af..ab985694b 100644 --- a/pyramid/tests/test_request.py +++ b/pyramid/tests/test_request.py @@ -266,6 +266,23 @@ class TestRequest(unittest.TestCase): self.assertEqual(result, 'http://example.com:5432/1/2/3/extra1/extra2?a=1#foo') + def test_route_path(self): + environ = { + 'PATH_INFO':'/', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'5432', + 'QUERY_STRING':'la=La%20Pe%C3%B1a', + 'wsgi.url_scheme':'http', + } + from pyramid.interfaces import IRoutesMapper + inst = self._makeOne(environ) + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + self.config.registry.registerUtility(mapper, IRoutesMapper) + result = inst.route_path('flub', 'extra1', 'extra2', + a=1, b=2, c=3, _query={'a':1}, + _anchor=u"foo") + self.assertEqual(result, '/1/2/3/extra1/extra2?a=1#foo') + def test_static_url(self): from pyramid.interfaces import IStaticURLInfo environ = { diff --git a/pyramid/tests/test_url.py b/pyramid/tests/test_url.py index 332ff3f11..aad969ca7 100644 --- a/pyramid/tests/test_url.py +++ b/pyramid/tests/test_url.py @@ -209,6 +209,27 @@ class TestRouteUrl(unittest.TestCase): self.assertEqual(result, 'http://example2.com/1/2/3/a') self.assertEqual(route.kw, {}) # shouldnt have anchor/query +class TestRoutePath(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _callFUT(self, *arg, **kw): + from pyramid.url import route_path + return route_path(*arg, **kw) + + def test_with_elements(self): + from pyramid.interfaces import IRoutesMapper + request = _makeRequest() + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = self._callFUT('flub', request, 'extra1', 'extra2', + a=1, b=2, c=3, _query={'a':1}, + _anchor=u"foo") + self.assertEqual(result, '/1/2/3/extra1/extra2?a=1#foo') + class TestStaticUrl(unittest.TestCase): def setUp(self): cleanUp() diff --git a/pyramid/url.py b/pyramid/url.py index fa15e6364..fca2582de 100644 --- a/pyramid/url.py +++ b/pyramid/url.py @@ -153,6 +153,33 @@ def route_url(route_name, request, *elements, **kw): return app_url + path + suffix + qs + anchor +def route_path(route_name, request, *elements, **kw): + """Generates a path (aka a 'relative URL', a URL minus the host, scheme, + and port) for a named :app:`Pyramid` :term:`route configuration`. + + .. note:: Calling :meth:`pyramid.Request.route_path` can be used to + achieve the same result as :func:`pyramid.url.route_path`. + + This function accepts the same argument as :func:`pyramid.url.route_url` + and performs the same duty. It just omits the host, port, and scheme + information in the return value; only the path, query parameters, + and anchor data are present in the returned string. + + For example, if you've defined a route named 'foobar' with the path + ``/:foo/:bar``, this call to ``route_path``:: + + route_path('foobar', request, foo='1', bar='2') + + Will return the string ``/1/2``. + + .. note:: Calling ``route_path('route', request)`` is the same as calling + ``route_url('route', request, _app_url='')``. ``route_path`` is, in + fact, implemented in terms of ``route_url`` in just this way. As a + result, passing ``_app_url`` within the ``**kw`` values passed to + ``route_path`` will result in an exception. + """ + return route_url(route_name, request, *elements, _app_url='', **kw) + def model_url(model, request, *elements, **kw): """ Generate a string representing the absolute URL of the ``model`` |
