summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt10
-rw-r--r--TODO.txt6
-rw-r--r--docs/narr/urldispatch.rst29
-rw-r--r--pyramid/config.py11
-rw-r--r--pyramid/interfaces.py3
-rw-r--r--pyramid/tests/test_config.py8
-rw-r--r--pyramid/tests/test_urldispatch.py23
-rw-r--r--pyramid/urldispatch.py8
8 files changed, 89 insertions, 9 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 0182bdce0..adf926ea2 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -32,6 +32,9 @@ Documentation
- Added documentation for a "multidict" (e.g. the API of ``request.POST``) as
interface API documentation.
+- Added a section to the "URL Dispatch" narrative chapter regarding the new
+ "static" route feature.
+
Features
--------
@@ -85,6 +88,13 @@ Features
section entitled "Displaying Matching Views for a Given URL" in the "View
Configuration" chapter of the narrative documentation for more information.
+- The ``add_route`` method of the Configurator now accepts a ``static``
+ argument. If this argument is ``True``, the added route will never be
+ considered for matching when a request is handled. Instead, it will only
+ be useful for URL generation via ``route_url`` and ``route_path``. See the
+ section entitled "Static Routes" in the URL Dispatch narrative chapter for
+ more information.
+
Bug Fixes
---------
diff --git a/TODO.txt b/TODO.txt
index 1429bd80c..b6fda3fbf 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -10,14 +10,10 @@ Should-Have
- Fix misleading conflict error reports for static views ala
http://cluebin.appspot.com/pasted/7242843
-- Nicer Mako exceptions in WebError.
-
- Consider adding a default exception view for HTTPException and attendant
``redirect`` and ``abort`` functions ala Pylons (promised Mike I'd enable
this in 1.1).
-- Static (URL-generation only) routes.
-
- Add narrative docs for wsgiapp and wsgiapp2.
- Fix message catalog extraction / compilation documentation. Chameleon 2
@@ -28,6 +24,8 @@ Should-Have
Nice-to-Have
------------
+- Nicer Mako exceptions in WebError.
+
- Response.RequestClass should probably be pyramid.request.Request but this
may imply actually subclassing webob.Response
diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst
index a180003d0..5df1eb3af 100644
--- a/docs/narr/urldispatch.rst
+++ b/docs/narr/urldispatch.rst
@@ -832,6 +832,35 @@ See the :func:`~pyramid.url.route_url` API documentation for more
information.
.. index::
+ single: static routes
+
+.. _static_route_narr:
+
+Static Routes
+-------------
+
+Routes may be added with a ``static`` keyword argument. For example:
+
+.. code-block:: python
+ :linenos:
+
+ config = Configurator()
+ config.add_route('page', '/page/{action}', static=True)
+
+Routes added with a ``True`` ``static`` keyword argument will never be
+considered for matching at request time. Static routes are useful for URL
+generation purposes only. As a result, it is usually nonsensical to provide
+other non-``name`` and non-``pattern`` arguments to
+:meth:`~pyramid.config.Configurator.add_route` when ``static`` is passed as
+``True``, as none of the other arguments will ever be employed. A single
+exception to this rule is use of the ``pregenerator`` argument, which is not
+ignored when ``static`` is ``True``.
+
+.. note:: the ``static`` argument to
+ :meth:`~pyramid.config.Configurator.add_route` is new as of :app:`Pyramid`
+ 1.1.
+
+.. index::
single: redirecting to slash-appended routes
.. _redirecting_to_slash_appended_routes:
diff --git a/pyramid/config.py b/pyramid/config.py
index 9286136cf..4e06a9b2e 100644
--- a/pyramid/config.py
+++ b/pyramid/config.py
@@ -1453,6 +1453,7 @@ class Configurator(object):
use_global_views=False,
path=None,
pregenerator=None,
+ static=False,
):
""" Add a :term:`route configuration` to the current
configuration state, as well as possibly a :term:`view
@@ -1542,6 +1543,14 @@ class Configurator(object):
that otherwise matches the context, request, and view name
(but which does not match the route_name predicate).
+ static
+
+ If ``static`` is ``True``, this route will never match an incoming
+ request; it will only be useful for URL generation. By default,
+ ``static`` is ``False``. See :ref:`static_route_narr`.
+
+ .. note:: New in :app:`Pyramid` 1.1.
+
Predicate Arguments
pattern
@@ -1798,7 +1807,7 @@ class Configurator(object):
self.action(discriminator, None)
return mapper.connect(name, pattern, factory, predicates=predicates,
- pregenerator=pregenerator)
+ pregenerator=pregenerator, static=static)
def get_routes_mapper(self):
""" Return the :term:`routes mapper` object associated with
diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py
index 617133052..07812e0cd 100644
--- a/pyramid/interfaces.py
+++ b/pyramid/interfaces.py
@@ -429,7 +429,8 @@ class IRoute(Interface):
class IRoutesMapper(Interface):
""" Interface representing a Routes ``Mapper`` object """
def get_routes():
- """ Return a sequence of Route objects registered in the mapper."""
+ """ Return a sequence of Route objects registered in the mapper.
+ Static routes will not be returned in this sequence."""
def has_routes():
""" Returns ``True`` if any route has been registered. """
diff --git a/pyramid/tests/test_config.py b/pyramid/tests/test_config.py
index 9f7873ab5..97a93616d 100644
--- a/pyramid/tests/test_config.py
+++ b/pyramid/tests/test_config.py
@@ -1898,6 +1898,14 @@ class ConfiguratorTests(unittest.TestCase):
route = config.add_route('name', 'path', factory=factory)
self.assertEqual(route.factory, factory)
+ def test_add_route_with_static(self):
+ config = self._makeOne(autocommit=True)
+ route = config.add_route('name', 'path/{foo}', static=True)
+ self.assertEqual(route.name, 'name')
+ mapper = config.get_routes_mapper()
+ self.assertEqual(len(mapper.get_routes()), 0)
+ self.assertEqual(mapper.generate('name', {"foo":"a"}), '/path/a')
+
def test_add_route_with_factory_dottedname(self):
config = self._makeOne(autocommit=True)
route = config.add_route(
diff --git a/pyramid/tests/test_urldispatch.py b/pyramid/tests/test_urldispatch.py
index 6e1474b1d..7df237aeb 100644
--- a/pyramid/tests/test_urldispatch.py
+++ b/pyramid/tests/test_urldispatch.py
@@ -90,6 +90,29 @@ class RoutesMapperTests(unittest.TestCase):
self.assertEqual(mapper.routelist[0].pattern,
'archives/:action/:article2')
+ def test_connect_static(self):
+ mapper = self._makeOne()
+ mapper.connect('foo', 'archives/:action/:article', static=True)
+ self.assertEqual(len(mapper.routelist), 0)
+ self.assertEqual(len(mapper.routes), 1)
+ self.assertEqual(mapper.routes['foo'].pattern,
+ 'archives/:action/:article')
+
+ def test_connect_static_overridden(self):
+ mapper = self._makeOne()
+ mapper.connect('foo', 'archives/:action/:article', static=True)
+ self.assertEqual(len(mapper.routelist), 0)
+ self.assertEqual(len(mapper.routes), 1)
+ self.assertEqual(mapper.routes['foo'].pattern,
+ 'archives/:action/:article')
+ mapper.connect('foo', 'archives/:action/:article2')
+ self.assertEqual(len(mapper.routelist), 1)
+ self.assertEqual(len(mapper.routes), 1)
+ self.assertEqual(mapper.routes['foo'].pattern,
+ 'archives/:action/:article2')
+ self.assertEqual(mapper.routelist[0].pattern,
+ 'archives/:action/:article2')
+
def test___call__route_matches(self):
mapper = self._makeOne()
mapper.connect('foo', 'archives/:action/:article')
diff --git a/pyramid/urldispatch.py b/pyramid/urldispatch.py
index 989cc62b9..43bc7e50f 100644
--- a/pyramid/urldispatch.py
+++ b/pyramid/urldispatch.py
@@ -42,12 +42,14 @@ class RoutesMapper(object):
return self.routes.get(name)
def connect(self, name, pattern, factory=None, predicates=(),
- pregenerator=None):
+ pregenerator=None, static=False):
if name in self.routes:
oldroute = self.routes[name]
- self.routelist.remove(oldroute)
+ if oldroute in self.routelist:
+ self.routelist.remove(oldroute)
route = Route(name, pattern, factory, predicates, pregenerator)
- self.routelist.append(route)
+ if not static:
+ self.routelist.append(route)
self.routes[name] = route
return route