diff options
| -rw-r--r-- | CHANGES.txt | 4 | ||||
| -rw-r--r-- | TODO.txt | 4 | ||||
| -rw-r--r-- | docs/api/request.rst | 4 | ||||
| -rw-r--r-- | pyramid/tests/test_url.py | 32 | ||||
| -rw-r--r-- | pyramid/url.py | 45 |
5 files changed, 86 insertions, 3 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index afcacd90b..90945105f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -75,6 +75,10 @@ Features - Better Mako rendering exceptions via ``pyramid.mako_templating.MakoRenderingException`` +- New request methods: ``current_route_url``, ``current_route_path``. + +- New function in ``pyramid.url``: ``current_route_path``. + Internal -------- @@ -11,8 +11,6 @@ Should-Have - Make it possible to use tween aliases in explicit tween config? If not, the tween factories of all add-ons must be APIs. -- Create a ``current_route_path`` function and make it a method of request? - - "static_path" API (omit host and port)? Nice-to-Have @@ -34,7 +32,7 @@ Nice-to-Have - Some sort of API for rendering a view callable object to a response from within another view callable. -- 1.4: turn ``pyramid.settings.Settings`` into a function that returns the +- 1.5: turn ``pyramid.settings.Settings`` into a function that returns the original dict (after ``__getattr__`` deprecation period, it was deprecated in 1.2). diff --git a/docs/api/request.rst b/docs/api/request.rst index 2ab3977d5..c7dc897a3 100644 --- a/docs/api/request.rst +++ b/docs/api/request.rst @@ -167,8 +167,12 @@ .. automethod:: route_url + .. automethod:: current_route_url + .. automethod:: route_path + .. automethod:: current_route_path + .. automethod:: resource_url .. automethod:: static_url diff --git a/pyramid/tests/test_url.py b/pyramid/tests/test_url.py index 652e5a8d2..ad55cae0b 100644 --- a/pyramid/tests/test_url.py +++ b/pyramid/tests/test_url.py @@ -298,6 +298,18 @@ class TestURLMethodsMixin(unittest.TestCase): self.assertEqual(result, 'http://example.com:5432/1/2/3/extra1/extra2?a=1#foo') + def test_current_route_path(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route=route) + request.matched_route = route + request.matchdict = {} + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.current_route_path('extra1', 'extra2', _query={'a':1}, + _anchor=u"foo") + self.assertEqual(result, '/1/2/3/extra1/extra2?a=1#foo') + def test_route_path_with_elements(self): from pyramid.interfaces import IRoutesMapper request = self._makeOne() @@ -466,6 +478,26 @@ class Test_current_route_url(unittest.TestCase): self.assertEqual(request.elements, ('abc',)) self.assertEqual(request.kw, {'_app_url':''}) +class Test_current_route_path(unittest.TestCase): + def _callFUT(self, request, *elements, **kw): + from pyramid.url import current_route_path + return current_route_path(request, *elements, **kw) + + def _makeRequest(self): + class Request(object): + def current_route_path(self, *elements, **kw): + self.elements = elements + self.kw = kw + return 'current route path' + return Request() + + def test_it(self): + request = self._makeRequest() + result = self._callFUT(request, 'abc', _anchor='abc') + self.assertEqual(result, 'current route path') + self.assertEqual(request.elements, ('abc',)) + self.assertEqual(request.kw, {'_anchor':'abc'}) + class DummyContext(object): def __init__(self, next=None): self.next = next diff --git a/pyramid/url.py b/pyramid/url.py index 254cd6d0e..73ffdbe25 100644 --- a/pyramid/url.py +++ b/pyramid/url.py @@ -427,6 +427,39 @@ class URLMethodsMixin(object): newkw.update(self.matchdict) newkw.update(kw) return self.route_url(route_name, *elements, **newkw) + + def current_route_path(self, *elements, **kw): + """ + Generates a path (aka a 'relative URL', a URL minus the host, scheme, + and port) for the :app:`Pyramid` :term:`route configuration` matched + by the current request. + + This function accepts the same argument as + :meth:`pyramid.request.Request.current_route_url` and performs the + same duty. It just omits the host, port, and scheme information in + the return value; only the script_name, path, query parameters, and + anchor data are present in the returned string. + + For example, if the route matched by the current request is named + 'foobar' with the path ``/{foo}/{bar}``, this call to + ``current_route_path``:: + + request.route_path(foo='1', bar='2') + + Will return the string ``/1/2``. + + .. note:: Calling ``request.current_route_path('route')`` is the same + as calling ``request.current_route_url('route', + _app_url=request.script_name)``. + :meth:`pyramid.request.Request.current_route_path` is, in fact, + implemented in terms of + `:meth:`pyramid.request.Request.current_route_url` in just this + way. As a result, any ``_app_url`` passed within the ``**kw`` + values to ``current_route_path`` will be ignored. + """ + kw['_app_url'] = '' + return self.current_route_url(*elements, **kw) + def route_url(route_name, request, *elements, **kw): """ @@ -492,6 +525,18 @@ def current_route_url(request, *elements, **kw): """ return request.current_route_url(*elements, **kw) +def current_route_path(request, *elements, **kw): + """ + This is a backwards compatibility function. Its result is the same as + calling:: + + request.current_route_path(*elements, **kw) + + See :meth:`pyramid.request.Request.current_route_path` for more + information. + """ + return request.current_route_path(*elements, **kw) + @lru_cache(1000) def _join_elements(elements): return '/'.join([quote_path_segment(s, safe=':@&+$,') for s in elements]) |
