diff options
| author | Chris McDonough <chrism@agendaless.com> | 2010-08-07 04:41:40 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2010-08-07 04:41:40 +0000 |
| commit | ab27bdb42d5b2c525466fe5570959f66b4814326 (patch) | |
| tree | e845ef721f21e4b651cd5bfcd32564ff18525855 | |
| parent | a48be71bca1caec1082061430f5787a0ebf7c249 (diff) | |
| download | pyramid-ab27bdb42d5b2c525466fe5570959f66b4814326.tar.gz pyramid-ab27bdb42d5b2c525466fe5570959f66b4814326.tar.bz2 pyramid-ab27bdb42d5b2c525466fe5570959f66b4814326.zip | |
Features
--------
- There can only be one Not Found view in any ``repoze.bfg``
application. If you use
``repoze.bfg.view.append_slash_notfound_view`` as the Not Found
view, it still must generate a NotFound response when it cannot
redirect to a slash-appended URL; this not found response will be
visible to site users.
As of this release, if you wish to use a custom notfound view
callable when ``append_slash_notfound_view`` does not redirect to a
slash-appended URL, use a wrapper function as the
``repoze.bfg.exceptions.NotFound`` view; have this wrapper attach a
view callable which returns a response to the request object named
``custom_notfound_view`` before calling
``append_slash_notfound_view``. For example::
from webob.exc import HTTPNotFound
from repoze.bfg.exceptions import NotFound
from repoze.bfg.view import append_slash_notfound_view
def notfound_view(exc, request):
def fallback_notfound_view(exc, request):
return HTTPNotFound('It aint there, stop trying!')
request.fallback_notfound_view = fallback_notfound_view
return append_slash_notfound_view(exc, request)
config.add_view(notfound_view, context=NotFound)
``custom_notfound_view`` must adhere to the two-argument view
callable calling convention of ``(context, request)`` (``context``
will be the exception object).
If ``custom_notfound_view`` is not found on the request object, a
default notfound response will be generated when the
``append_slash_notfound_view`` doesn't redirect to a slash-appended
URL.
Documentation
--------------
- Expanded the "Cleaning Up After a Request" section of the URL
Dispatch narrative chapter.
- Expanded the "Redirecting to Slash-Appended Routes" section of the
URL Dispatch narrative chapter.
| -rw-r--r-- | CHANGES.txt | 51 | ||||
| -rw-r--r-- | docs/narr/urldispatch.rst | 47 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_view.py | 9 | ||||
| -rw-r--r-- | repoze/bfg/view.py | 44 |
4 files changed, 148 insertions, 3 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 1c62b25ff..65a08a781 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,54 @@ +Next release +============ + +Features +-------- + +- There can only be one Not Found view in any ``repoze.bfg`` + application. If you use + ``repoze.bfg.view.append_slash_notfound_view`` as the Not Found + view, it still must generate a NotFound response when it cannot + redirect to a slash-appended URL; this not found response will be + visible to site users. + + As of this release, if you wish to use a custom notfound view + callable when ``append_slash_notfound_view`` does not redirect to a + slash-appended URL, use a wrapper function as the + ``repoze.bfg.exceptions.NotFound`` view; have this wrapper attach a + view callable which returns a response to the request object named + ``custom_notfound_view`` before calling + ``append_slash_notfound_view``. For example:: + + from webob.exc import HTTPNotFound + from repoze.bfg.exceptions import NotFound + from repoze.bfg.view import append_slash_notfound_view + + def notfound_view(exc, request): + def fallback_notfound_view(exc, request): + return HTTPNotFound('It aint there, stop trying!') + request.fallback_notfound_view = fallback_notfound_view + return append_slash_notfound_view(exc, request) + + config.add_view(notfound_view, context=NotFound) + + ``custom_notfound_view`` must adhere to the two-argument view + callable calling convention of ``(context, request)`` (``context`` + will be the exception object). + + If ``custom_notfound_view`` is not found on the request object, a + default notfound response will be generated when the + ``append_slash_notfound_view`` doesn't redirect to a slash-appended + URL. + +Documentation +-------------- + +- Expanded the "Cleaning Up After a Request" section of the URL + Dispatch narrative chapter. + +- Expanded the "Redirecting to Slash-Appended Routes" section of the + URL Dispatch narrative chapter. + 1.3a7 (2010-08-01) ================== diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 916715bec..6e3a68c97 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1058,6 +1058,8 @@ information. .. index:: single: redirecting to slash-appended routes +.. _redirecting_to_slash_appended_routes: + Redirecting to Slash-Appended Routes ------------------------------------ @@ -1114,12 +1116,24 @@ stanza: view="repoze.bfg.view.append_slash_notfound_view" /> +Or use the :meth:`repoze.bfg.configuration.Configurator.add_view` +method if you don't use ZCML: + +.. code-block:: python + :linenos: + + from repoze.bfg.exceptions import NotFound + from repoze.bfg.view import append_slash_notfound_view + config.add_view(append_slash_notfound_view, context=NotFound) + See :ref:`view_module` and :ref:`changing_the_notfound_view` for more information about the slash-appending not found view and for a more general description of how to configure a not found view. .. note:: This feature is new as of :mod:`repoze.bfg` 1.1. +.. _cleaning_up_after_a_request: + Cleaning Up After a Request --------------------------- @@ -1164,8 +1178,37 @@ Then in the ``configure.zcml`` of your package, inject the following: <subscriber for="repoze.bfg.interfaces.INewRequest" handler="mypackage.run.handle_teardown"/> -This will cause the DBSession to be removed whenever the WSGI -environment is destroyed (usually at the end of every request). +Or, if you don't use ZCML, but you do use a :term:`scan` add a +subscriber decorator: + +.. code-block:: python + + from repoze.bfg.events import subscriber + from repoze.bfg.interfaces import INewRequest + + @subscriber(INewRequest) + def handle_teardown(event): + environ = event.request.environ + environ['mypackage.sqlcleaner'] = Cleanup(DBSession.remove) + +Or finally, it can be done imperatively via the ``add_subscriber`` +method of a :term:`Configurator`. + +.. code-block:: python + + from repoze.bfg.interfaces import INewRequest + from repoze.bfg.configuration imoport Configurator + + def handle_teardown(event): + environ = event.request.environ + environ['mypackage.sqlcleaner'] = Cleanup(DBSession.remove) + + config = Configurator() + config.add_subscriber(handle_teardown, INewRequest) + +Any of the above three ways to register a handle_teardown subscriber +will cause the DBSession to be removed whenever the WSGI environment +is destroyed (usually at the end of every request). .. note:: This is only an example. In particular, it is not necessary to cause ``DBSession.remove`` to be called as the result of an diff --git a/repoze/bfg/tests/test_view.py b/repoze/bfg/tests/test_view.py index bb178029c..27f468c74 100644 --- a/repoze/bfg/tests/test_view.py +++ b/repoze/bfg/tests/test_view.py @@ -429,6 +429,15 @@ class AppendSlashNotFoundView(BaseTest, unittest.TestCase): response = self._callFUT(context, request) self.assertEqual(response.status, '404 Not Found') + def test_custom_notfound_view(self): + request = self._makeRequest(PATH_INFO='/abc') + def notfound(exc, request): + return 'abc' + request.custom_notfound_view = notfound + context = Exception() + response = self._callFUT(context, request) + self.assertEqual(response, 'abc') + def test_no_path(self): request = self._makeRequest() context = Exception() diff --git a/repoze/bfg/view.py b/repoze/bfg/view.py index 7a853eb28..30076b775 100644 --- a/repoze/bfg/view.py +++ b/repoze/bfg/view.py @@ -516,6 +516,46 @@ def append_slash_notfound_view(context, request): .. note:: This function is new as of :mod:`repoze.bfg` version 1.1. + There can only be one Not Found view in any :mod:`repoze.bfg + application. If you use ``append_slash_notfound_view`` as the Not + Found view, it still must generate a NotFound response when it + cannot redirect to a slash-appended URL; this not found response + will be visible to site users. + + If you wish to use a custom notfound view callable when + ``append_slash_notfound_view`` does not redirect to a + slash-appended URL, use a wrapper function as the + :exc:`repoze.bfg.exceptions.NotFound` view; have this wrapper + attach a :term:`view callable` which returns a response to the + request object named ``custom_notfound_view`` before calling + ``append_slash_notfound_view``. For example: + + .. code-block:: python + + from webob.exc import HTTPNotFound + from repoze.bfg.exceptions import NotFound + from repoze.bfg.view import append_slash_notfound_view + + def notfound_view(exc, request): + def fallback_notfound_view(exc, request): + return HTTPNotFound('It aint there, stop trying!') + request.fallback_notfound_view = fallback_notfound_view + return append_slash_notfound_view(exc, request) + + config.add_view(notfound_view, context=NotFound) + + ``custom_notfound_view`` must adhere to the two-argument view + callable calling convention of ``(context, request)`` (``context`` + will be the exception object). + + If ``custom_notfound_view`` is not found on the request object, a + default notfound response will be generated when the + ``append_slash_notfound_view`` doesn't redirect to a + slash-appended URL. + + .. note:: The checking for ``request.custom_notfound_view`` by + ``append_slash_notfound_view`` is new as of :mod:`repoze.bfg` + version 1.3. """ if not isinstance(context, Exception): # backwards compat for an append_notslash_view registered via @@ -529,5 +569,7 @@ def append_slash_notfound_view(context, request): for route in mapper.get_routes(): if route.match(slashpath) is not None: return HTTPFound(location=slashpath) - return default_view(context, request, '404 Not Found') + notfound_view = getattr(request, 'custom_notfound_view', + default_notfound_view) + return notfound_view(context, request) |
