diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-06-24 04:04:06 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-06-24 04:04:06 +0000 |
| commit | dc405b2e9bac8e43350442a7824901f5ced8e3d5 (patch) | |
| tree | 9848b737b83471905ad95df6e34c12f568398c53 | |
| parent | affef3124f49441989522a5c87589d37a9b8585a (diff) | |
| download | pyramid-dc405b2e9bac8e43350442a7824901f5ced8e3d5.tar.gz pyramid-dc405b2e9bac8e43350442a7824901f5ced8e3d5.tar.bz2 pyramid-dc405b2e9bac8e43350442a7824901f5ced8e3d5.zip | |
- Added the ``repoze.bfg.url.route_url`` API. This is meant to
"front" for the Routes ``url_for`` API. See the URL Dispatch
narrative chapter and the "repoze.bfg.url" module API documentation
for more information.
| -rw-r--r-- | CHANGES.txt | 8 | ||||
| -rw-r--r-- | docs/api/url.rst | 2 | ||||
| -rw-r--r-- | docs/narr/urldispatch.rst | 16 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_url.py | 44 | ||||
| -rw-r--r-- | repoze/bfg/url.py | 34 |
5 files changed, 104 insertions, 0 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 597c29684..0ee8bb093 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -13,6 +13,14 @@ Documentation - Added a "corner case" explanation to the "Hybrid Apps" chapter explaining what to do when "the wrong" view is matched. +Features +-------- + +- Added the ``repoze.bfg.url.route_url`` API. This is meant to + "front" for the Routes ``url_for`` API. See the URL Dispatch + narrative chapter and the "repoze.bfg.url" module API documentation + for more information. + 1.0a2 (2009-06-23) ================== diff --git a/docs/api/url.rst b/docs/api/url.rst index d984dcc07..36d3c5b65 100644 --- a/docs/api/url.rst +++ b/docs/api/url.rst @@ -7,5 +7,7 @@ .. autofunction:: model_url + .. autofunction:: route_url + .. autofunction:: urlencode diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index f62a682c9..dab026455 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -388,6 +388,22 @@ declaration: view=".views.root_view" /> +Generating Route URLs +--------------------- + +Use the :mod:`repoze.bfg.url.route_url` function to generate URLs +based on route paths. For example, if you've configured a route in +ZCML with the ``name`` "foo" and the ``path`` ":a/:b/:c", you might do +this. + +.. code-block:: python + + from repoze.bfg.url import route_url + url = route_url('foo', a='1', b='2', c='3') + +This would return something like the string +``http://example.com/1/2/3``. + Cleaning Up After a Request --------------------------- diff --git a/repoze/bfg/tests/test_url.py b/repoze/bfg/tests/test_url.py index 64cf52383..e42089173 100644 --- a/repoze/bfg/tests/test_url.py +++ b/repoze/bfg/tests/test_url.py @@ -156,6 +156,50 @@ class UrlEncodeTests(unittest.TestCase): def test_dict(self): result = self._callFUT({'a':1}) self.assertEqual(result, 'a=1') + +class TestRouteUrl(unittest.TestCase): + def _callFUT(self, *arg, **kw): + from repoze.bfg.url import route_url + return route_url(*arg, **kw) + + def test_it(self): + from routes import Mapper + mapper = Mapper(controller_scan=None, directory=None, + explicit=True, always_scan=False) + args = {'a':'1', 'b':'2', 'c':'3'} + mapper.connect('flub', ':a/:b/:c') + mapper.create_regs([]) + environ = {'SERVER_NAME':'example.com', 'wsgi.url_scheme':'http', + 'SERVER_PORT':'80', 'wsgiorg.routing_args':((), args)} + mapper.environ = environ + from routes import request_config + config = request_config() + config.environ = environ + config.mapper = mapper + config.redirect = None + request = DummyRequest() + request.environ = environ + result = self._callFUT('flub', a=1, b=2, c=3) + self.assertEqual(result, 'http://example.com/1/2/3') + + def test_it_generation_error(self): + from routes import Mapper + mapper = Mapper(controller_scan=None, directory=None, + explicit=True, always_scan=False) + args = {'a':'1', 'b':'2', 'c':'3'} + mapper.connect('flub', ':a/:b/:c') + mapper.create_regs([]) + environ = {'SERVER_NAME':'example.com', 'wsgi.url_scheme':'http', + 'SERVER_PORT':'80', 'wsgiorg.routing_args':((), args)} + mapper.environ = environ + from routes import request_config + config = request_config() + config.environ = environ + config.mapper = mapper + config.redirect = None + request = DummyRequest() + request.environ = environ + self.assertRaises(ValueError, self._callFUT, 'flub', a=1) class DummyContext(object): def __init__(self, next=None): diff --git a/repoze/bfg/url.py b/repoze/bfg/url.py index 528d83ae9..d3fc55203 100644 --- a/repoze/bfg/url.py +++ b/repoze/bfg/url.py @@ -8,6 +8,40 @@ from repoze.bfg.interfaces import IContextURL from repoze.bfg.traversal import TraversalContextURL from repoze.bfg.traversal import quote_path_segment +from routes import url_for +from routes.util import GenerationException + +def route_url(*arg, **kw): + """Generates a fully qualified URL for a named BFG route. + + Use the route's ``name`` as the first positional argument. Use + keyword arguments to supply values which match any dynamic path + elements in the route definition. Raises a ValueError exception + if the URL cannot be generated when the + + For example, if you've defined a route named"foobar" with the path + ``:foo/:bar/*traverse``:: + + route_url(foo='1') => <ValueError exception> + route_url(foo='1', bar='2') => <ValueError exception> + route_url(foo='1', bar='2',traverse='a/b) => http://e.com/1/2/a/b + + All keys given to ``route_url`` are sent to the BFG Routes "mapper" + instance for generation except for:: + + anchor specifies the anchor name to be appened to the path + host overrides the default host if provided + protocol overrides the default (current) protocol if provided + qualified return a fully qualified URL (default True) + + """ + if not 'qualified' in kw: + kw['qualified'] = True + try: + return url_for(*arg, **kw) + except GenerationException, why: + raise ValueError(str(why)) + def model_url(model, request, *elements, **kw): """ Generate a string representing the absolute URL of the model (or |
