summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-06-24 04:04:06 +0000
committerChris McDonough <chrism@agendaless.com>2009-06-24 04:04:06 +0000
commitdc405b2e9bac8e43350442a7824901f5ced8e3d5 (patch)
tree9848b737b83471905ad95df6e34c12f568398c53
parentaffef3124f49441989522a5c87589d37a9b8585a (diff)
downloadpyramid-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.txt8
-rw-r--r--docs/api/url.rst2
-rw-r--r--docs/narr/urldispatch.rst16
-rw-r--r--repoze/bfg/tests/test_url.py44
-rw-r--r--repoze/bfg/url.py34
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