summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2010-12-26 01:13:26 -0500
committerChris McDonough <chrism@plope.com>2010-12-26 01:13:26 -0500
commite1a7e0679759da628676f3c73c34875e9b2b6a43 (patch)
tree24fde2f1d7315c457a5a02094a684e762307a1d6 /docs
parentf5bafd1da8da405936bae032d20dba545922860e (diff)
downloadpyramid-e1a7e0679759da628676f3c73c34875e9b2b6a43.tar.gz
pyramid-e1a7e0679759da628676f3c73c34875e9b2b6a43.tar.bz2
pyramid-e1a7e0679759da628676f3c73c34875e9b2b6a43.zip
- Move ZCML usage in Hooks chapter to Declarative Configuration chapter.
Diffstat (limited to 'docs')
-rw-r--r--docs/narr/declarative.rst140
-rw-r--r--docs/narr/hooks.rst470
2 files changed, 338 insertions, 272 deletions
diff --git a/docs/narr/declarative.rst b/docs/narr/declarative.rst
index deccb6c48..12deb90e7 100644
--- a/docs/narr/declarative.rst
+++ b/docs/narr/declarative.rst
@@ -1266,9 +1266,143 @@ which we assume lives in a ``subscribers.py`` module within your application:
See also :ref:`subscriber_directive` and :ref:`events_chapter`.
+.. index::
+ single: not found view
+
+.. _notfound_zcml:
+
+Configuring a Not Found View via ZCML
+-------------------------------------
+
+If your application uses :term:`ZCML`, you can replace the Not Found view by
+placing something like the following ZCML in your ``configure.zcml`` file.
+
+.. code-block:: xml
+ :linenos:
+
+ <view
+ view="helloworld.views.notfound_view"
+ context="pyramid.exceptions.NotFound"
+ />
+
+Replace ``helloworld.views.notfound_view`` with the Python dotted name to the
+notfound view you want to use.
+
+See :ref:`changing_the_notfound_view` for more information.
+
+.. index::
+ single: forbidden view
+
+.. _forbidden_zcml:
+
+Configuring a Forbidden View via ZCML
+-------------------------------------
+
+If your application uses :term:`ZCML`, you can replace the Forbidden view by
+placing something like the following ZCML in your ``configure.zcml`` file.
+
+.. code-block:: xml
+ :linenos:
+
+ <view
+ view="helloworld.views.notfound_view"
+ context="pyramid.exceptions.Forbidden"
+ />
+
+Replace ``helloworld.views.forbidden_view`` with the Python dotted name to
+the forbidden view you want to use.
+
+See :ref:`changing_the_forbidden_view` for more information.
+
+.. _changing_traverser_zcml:
+
+Configuring an Alternate Traverser via ZCML
+-------------------------------------------
+
+Use an ``adapter`` stanza in your application's ``configure.zcml`` to
+change the default traverser:
+
+.. code-block:: xml
+ :linenos:
+
+ <adapter
+ factory="myapp.traversal.Traverser"
+ provides="pyramid.interfaces.ITraverser"
+ for="*"
+ />
+
+Or to register a traverser for a specific resource type:
-.. Todo
-.. ----
+.. code-block:: xml
+ :linenos:
+
+ <adapter
+ factory="myapp.traversal.Traverser"
+ provides="pyramid.interfaces.ITraverser"
+ for="myapp.resources.MyRoot"
+ />
+
+See :ref:`changing_the_traverser` for more information.
+
+.. index::
+ single: url generator
+
+.. _changing_resource_url_zcml:
+
+Changing ``resource_url`` URL Generation via ZCML
+-------------------------------------------------
+
+You can change how :func:`pyramid.url.resource_url` generates a URL for a
+specific type of resource by adding an adapter statement to your
+``configure.zcml``.
+
+.. code-block:: xml
+ :linenos:
+
+ <adapter
+ factory="myapp.traversal.URLGenerator"
+ provides="pyramid.interfaces.IContextURL"
+ for="myapp.resources.MyRoot *"
+ />
+
+See :ref:`changing_resource_url` for more information.
+
+.. _changing_request_factory_zcml:
+
+Changing the Request Factory via ZCML
+-------------------------------------
+
+A ``MyRequest`` class can be registered via ZCML as a request factory through
+the use of the ZCML ``utility`` directive. In the below, we assume it lives
+in a package named ``mypackage.mymodule``.
+
+.. code-block:: xml
+ :linenos:
+
+ <utility
+ component="mypackage.mymodule.MyRequest"
+ provides="pyramid.interfaces.IRequestFactory"
+ />
+
+See :ref:`changing_request_factory` for more information.
+
+.. _adding_renderer_globals_zcml:
+
+Changing the Renderer Globals Factory via ZCML
+----------------------------------------------
+
+A renderer globals factory can be registered via ZCML as a through the use of
+the ZCML ``utility`` directive. In the below, we assume a
+``renderers_globals_factory`` function lives in a package named
+``mypackage.mymodule``.
+
+.. code-block:: xml
+ :linenos:
+
+ <utility
+ component="mypackage.mymodule.renderer_globals_factory"
+ provides="pyramid.interfaces.IRendererGlobalsFactory"
+ />
-.. - hooks chapter still has topics for ZCML
+See :ref:`adding_renderer_globals` for more information.
diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst
index 006f5d5cb..381da0d39 100644
--- a/docs/narr/hooks.rst
+++ b/docs/narr/hooks.rst
@@ -3,8 +3,8 @@
Using Hooks
===========
-"Hooks" can be used to influence the behavior of the :app:`Pyramid`
-framework in various ways.
+"Hooks" can be used to influence the behavior of the :app:`Pyramid` framework
+in various ways.
.. index::
single: not found view
@@ -14,61 +14,38 @@ framework in various ways.
Changing the Not Found View
---------------------------
-When :app:`Pyramid` can't map a URL to view code, it invokes a
-:term:`not found view`, which is a :term:`view callable`. A default
-notfound view exists. The default not found view can be overridden
-through application configuration. This override can be done via
-:term:`imperative configuration` or :term:`ZCML`.
+When :app:`Pyramid` can't map a URL to view code, it invokes a :term:`not
+found view`, which is a :term:`view callable`. A default notfound view
+exists. The default not found view can be overridden through application
+configuration.
-The :term:`not found view` callable is a view callable like any other.
-The :term:`view configuration` which causes it to be a "not found"
-view consists only of naming the :exc:`pyramid.exceptions.NotFound`
-class as the ``context`` of the view configuration.
+The :term:`not found view` callable is a view callable like any other. The
+:term:`view configuration` which causes it to be a "not found" view consists
+only of naming the :exc:`pyramid.exceptions.NotFound` class as the
+``context`` of the view configuration.
-.. topic:: Using Imperative Configuration
+If your application uses :term:`imperative configuration`, you can replace
+the Not Found view by using the :meth:`pyramid.config.Configurator.add_view`
+method to register an "exception view":
- If your application uses :term:`imperative configuration`, you can
- replace the Not Found view by using the
- :meth:`pyramid.config.Configurator.add_view` method to
- register an "exception view":
-
- .. code-block:: python
- :linenos:
-
- from pyramid.exceptions import NotFound
- from helloworld.views import notfound_view
- config.add_view(notfound_view, context=NotFound)
-
- Replace ``helloworld.views.notfound_view`` with a reference to the
- Python :term:`view callable` you want to use to represent the Not
- Found view.
-
-.. topic:: Using ZCML
-
- If your application uses :term:`ZCML`, you can replace the Not Found
- view by placing something like the following ZCML in your
- ``configure.zcml`` file.
-
- .. code-block:: xml
- :linenos:
+.. code-block:: python
+ :linenos:
- <view
- view="helloworld.views.notfound_view"
- context="pyramid.exceptions.NotFound"
- />
+ from pyramid.exceptions import NotFound
+ from helloworld.views import notfound_view
+ config.add_view(notfound_view, context=NotFound)
- Replace ``helloworld.views.notfound_view`` with the Python dotted name
- to the notfound view you want to use.
+Replace ``helloworld.views.notfound_view`` with a reference to the
+:term:`view callable` you want to use to represent the Not Found view.
-Like any other view, the notfound view must accept at least a
-``request`` parameter, or both ``context`` and ``request``. The
-``request`` is the current :term:`request` representing the denied
-action. The ``context`` (if used in the call signature) will be the
-instance of the :exc:`pyramid.exceptions.NotFound` exception that
-caused the view to be called.
+Like any other view, the notfound view must accept at least a ``request``
+parameter, or both ``context`` and ``request``. The ``request`` is the
+current :term:`request` representing the denied action. The ``context`` (if
+used in the call signature) will be the instance of the
+:exc:`pyramid.exceptions.NotFound` exception that caused the view to be
+called.
-Here's some sample code that implements a minimal NotFound view
-callable:
+Here's some sample code that implements a minimal NotFound view callable:
.. code-block:: python
:linenos:
@@ -93,6 +70,9 @@ callable:
:exc:`pyramid.exceptions.NotFound` exception instance. If available, the
resource context will still be available as ``request.context``.
+For information about how to configure a not found view via :term:`ZCML`, see
+:ref:`notfound_zcml`.
+
.. index::
single: forbidden view
@@ -101,59 +81,36 @@ callable:
Changing the Forbidden View
---------------------------
-When :app:`Pyramid` can't authorize execution of a view based on
-the :term:`authorization policy` in use, it invokes a :term:`forbidden
-view`. The default forbidden response has a 401 status code and is
-very plain, but the view which generates it can be overridden as
-necessary using either :term:`imperative configuration` or
-:term:`ZCML`.
-
-The :term:`forbidden view` callable is a view callable like any other.
-The :term:`view configuration` which causes it to be a "not found"
-view consists only of naming the :exc:`pyramid.exceptions.Forbidden`
-class as the ``context`` of the view configuration.
+When :app:`Pyramid` can't authorize execution of a view based on the
+:term:`authorization policy` in use, it invokes a :term:`forbidden view`.
+The default forbidden response has a 401 status code and is very plain, but
+the view which generates it can be overridden as necessary.
-.. topic:: Using Imperative Configuration
+The :term:`forbidden view` callable is a view callable like any other. The
+:term:`view configuration` which causes it to be a "not found" view consists
+only of naming the :exc:`pyramid.exceptions.Forbidden` class as the
+``context`` of the view configuration.
- If your application uses :term:`imperative configuration`, you can
- replace the Forbidden view by using the
- :meth:`pyramid.config.Configurator.add_view` method to
- register an "exception view":
+You can replace the forbidden view by using the
+:meth:`pyramid.config.Configurator.add_view` method to register an "exception
+view":
- .. code-block:: python
- :linenos:
-
- from helloworld.views import forbidden_view
- from pyramid.exceptions import Forbidden
- config.add_view(forbidden_view, context=Forbidden)
-
- Replace ``helloworld.views.forbidden_view`` with a reference to the
- Python :term:`view callable` you want to use to represent the
- Forbidden view.
-
-.. topic:: Using ZCML
-
- If your application uses :term:`ZCML`, you can replace the
- Forbidden view by placing something like the following ZCML in your
- ``configure.zcml`` file.
-
- .. code-block:: xml
- :linenos:
+.. code-block:: python
+ :linenos:
- <view
- view="helloworld.views.notfound_view"
- context="pyramid.exceptions.Forbidden"
- />
+ from helloworld.views import forbidden_view
+ from pyramid.exceptions import Forbidden
+ config.add_view(forbidden_view, context=Forbidden)
- Replace ``helloworld.views.forbidden_view`` with the Python
- dotted name to the forbidden view you want to use.
+Replace ``helloworld.views.forbidden_view`` with a reference to the Python
+:term:`view callable` you want to use to represent the Forbidden view.
-Like any other view, the forbidden view must accept at least a
-``request`` parameter, or both ``context`` and ``request``. The
-``context`` (available as ``request.context`` if you're using the
-request-only view argument pattern) is the context found by the router
-when the view invocation was denied. The ``request`` is the current
-:term:`request` representing the denied action.
+Like any other view, the forbidden view must accept at least a ``request``
+parameter, or both ``context`` and ``request``. The ``context`` (available
+as ``request.context`` if you're using the request-only view argument
+pattern) is the context found by the router when the view invocation was
+denied. The ``request`` is the current :term:`request` representing the
+denied action.
Here's some sample code that implements a minimal forbidden view:
@@ -161,10 +118,10 @@ Here's some sample code that implements a minimal forbidden view:
:linenos:
from pyramid.views import view_config
+ from pyramid.response import Response
- @view_config(renderer='templates/login_form.pt')
def forbidden_view(request):
- return {}
+ return Response('forbidden')
.. note:: When a forbidden view callable is invoked, it is passed a
:term:`request`. The ``exception`` attribute of the request will
@@ -181,6 +138,9 @@ Here's some sample code that implements a minimal forbidden view:
an alternate forbidden view. For example, it would make sense to
return a response with a ``403 Forbidden`` status code.
+For information about how to configure a forbidden view via :term:`ZCML`, see
+:ref:`forbidden_zcml`.
+
.. index::
single: traverser
@@ -189,25 +149,22 @@ Here's some sample code that implements a minimal forbidden view:
Changing the Traverser
----------------------
-The default :term:`traversal` algorithm that :app:`Pyramid` uses is
-explained in :ref:`traversal_algorithm`. Though it is rarely
-necessary, this default algorithm can be swapped out selectively for a
-different traversal pattern via configuration.
+The default :term:`traversal` algorithm that :app:`Pyramid` uses is explained
+in :ref:`traversal_algorithm`. Though it is rarely necessary, this default
+algorithm can be swapped out selectively for a different traversal pattern
+via configuration.
-Use an ``adapter`` stanza in your application's ``configure.zcml`` to
-change the default traverser:
-
-.. code-block:: xml
+.. code-block:: python
:linenos:
- <adapter
- factory="myapp.traversal.Traverser"
- provides="pyramid.interfaces.ITraverser"
- for="*"
- />
+ from pyramid.interfaces import ITraverser
+ from zope.interface import Interface
+ from myapp.traversal import Traverser
-In the example above, ``myapp.traversal.Traverser`` is assumed to be
-a class that implements the following interface:
+ config.registry.registerAdapter(Traverser, (Interface,), ITraverser)
+
+In the example above, ``myapp.traversal.Traverser`` is assumed to be a class
+that implements the following interface:
.. code-block:: python
:linenos:
@@ -241,31 +198,36 @@ a class that implements the following interface:
"""
More than one traversal algorithm can be active at the same time. For
-instance, if your :term:`root factory` returns more than one type of
-object conditionally, you could claim that an alternate traverser
-adapter is ``for`` only one particular class or interface. When the
-root factory returned an object that implemented that class or
-interface, a custom traverser would be used. Otherwise, the default
-traverser would be used. For example:
-
-.. code-block:: xml
+instance, if your :term:`root factory` returns more than one type of object
+conditionally, you could claim that an alternate traverser adapter is ``for``
+only one particular class or interface. When the root factory returned an
+object that implemented that class or interface, a custom traverser would be
+used. Otherwise, the default traverser would be used. For example:
+
+.. code-block:: python
:linenos:
- <adapter
- factory="myapp.traversal.Traverser"
- provides="pyramid.interfaces.ITraverser"
- for="myapp.resources.MyRoot"
- />
+ from pyramid.interfaces import ITraverser
+ from zope.interface import Interface
+ from myapp.traversal import Traverser
+ from myapp.resources import MyRoot
-If the above stanza was added to a ``configure.zcml`` file,
-:app:`Pyramid` would use the ``myapp.traversal.Traverser`` only
+ config.registry.registerAdapter(Traverser, (MyRoot,), ITraverser)
+
+If the above stanza was added to a Pyramid ``__init__.py`` file's ``main``
+function, :app:`Pyramid` would use the ``myapp.traversal.Traverser`` only
when the application :term:`root factory` returned an instance of the
``myapp.resources.MyRoot`` object. Otherwise it would use the default
:app:`Pyramid` traverser to do traversal.
+For information about how to configure an alternate traverser via
+:term:`ZCML`, see :ref:`changing_traverser_zcml`.
+
.. index::
single: url generator
+.. _changing_resource_url:
+
Changing How :mod:`pyramid.url.resource_url` Generates a URL
------------------------------------------------------------
@@ -276,25 +238,27 @@ generates by default may be incorrect.
If you've added a traverser, you can change how
:func:`pyramid.url.resource_url` generates a URL for a specific type of
-resource by adding an adapter stanza for
-:class:`pyramid.interfaces.IContextURL` to your application's
-``configure.zcml``:
+resource by adding a registerAdapter call for
+:class:`pyramid.interfaces.IContextURL` to your application:
-.. code-block:: xml
+.. code-block:: python
:linenos:
- <adapter
- factory="myapp.traversal.URLGenerator"
- provides="pyramid.interfaces.IContextURL"
- for="myapp.resources.MyRoot *"
- />
+ from pyramid.interfaces import ITraverser
+ from zope.interface import Interface
+ from myapp.traversal import URLGenerator
+ from myapp.resources import MyRoot
+
+ config.registry.registerAdapter(URLGenerator, (MyRoot, Interface),
+ IContextURL)
-In the above example, the ``myapp.traversal.URLGenerator`` class will
-be used to provide services to :func:`pyramid.url.resource_url` any
-time the :term:`context` passed to ``resource_url`` is of class
-``myapp.resources.MyRoot``. The asterisk following represents the type
-of interface that must be possessed by the :term:`request` (in this
-case, any interface, represented by asterisk).
+In the above example, the ``myapp.traversal.URLGenerator`` class will be used
+to provide services to :func:`pyramid.url.resource_url` any time the
+:term:`context` passed to ``resource_url`` is of class
+``myapp.resources.MyRoot``. The second argument in the ``(MyRoot,
+Interface)`` tuple represents the type of interface that must be possessed by
+the :term:`request` (in this case, any interface, represented by
+``zope.interface.Interface``).
The API that must be implemented by a class that provides
:class:`pyramid.interfaces.IContextURL` is as follows:
@@ -317,28 +281,25 @@ The API that must be implemented by a class that provides
def __call__(self):
""" Return a URL that points to the context """
-The default context URL generator is available for perusal as the
-class :class:`pyramid.traversal.TraversalContextURL` in the
-`traversal module
-<http://github.com/Pylons/pyramid/blob/master/pyramid/traversal.py>`_ of
-the :term:`Pylons` GitHub Pyramid repository.
+The default context URL generator is available for perusal as the class
+:class:`pyramid.traversal.TraversalContextURL` in the `traversal module
+<http://github.com/Pylons/pyramid/blob/master/pyramid/traversal.py>`_ of the
+:term:`Pylons` GitHub Pyramid repository.
.. _changing_the_request_factory:
Changing the Request Factory
----------------------------
-Whenever :app:`Pyramid` handles a :term:`WSGI` request, it creates
-a :term:`request` object based on the WSGI environment it has been
-passed. By default, an instance of the
-:class:`pyramid.request.Request` class is created to represent the
-request object.
+Whenever :app:`Pyramid` handles a :term:`WSGI` request, it creates a
+:term:`request` object based on the WSGI environment it has been passed. By
+default, an instance of the :class:`pyramid.request.Request` class is created
+to represent the request object.
-The class (aka "factory") that :app:`Pyramid` uses to create a
-request object instance can be changed by passing a
-``request_factory`` argument to the constructor of the
-:term:`configurator`. This argument can be either a callable or a
-:term:`dotted Python name` representing a callable.
+The class (aka "factory") that :app:`Pyramid` uses to create a request object
+instance can be changed by passing a ``request_factory`` argument to the
+constructor of the :term:`configurator`. This argument can be either a
+callable or a :term:`dotted Python name` representing a callable.
.. code-block:: python
:linenos:
@@ -350,24 +311,9 @@ request object instance can be changed by passing a
config = Configurator(request_factory=MyRequest)
-The same ``MyRequest`` class can alternately be registered via ZCML as
-a request factory through the use of the ZCML ``utility`` directive.
-In the below, we assume it lives in a package named
-``mypackage.mymodule``.
-
-.. code-block:: xml
- :linenos:
-
- <utility
- component="mypackage.mymodule.MyRequest"
- provides="pyramid.interfaces.IRequestFactory"
- />
-
-Lastly, if you're doing imperative configuration, and you'd rather do
-it after you've already constructed a :term:`configurator` it can also
-be registered via the
-:meth:`pyramid.config.Configurator.set_request_factory`
-method:
+If you're doing imperative configuration, and you'd rather do it after you've
+already constructed a :term:`configurator` it can also be registered via the
+:meth:`pyramid.config.Configurator.set_request_factory` method:
.. code-block:: python
:linenos:
@@ -381,26 +327,26 @@ method:
config = Configurator()
config.set_request_factory(MyRequest)
+To use ZCML for the same purpose, see :ref:`changing_request_factory_zcml`.
+
.. _adding_renderer_globals:
Adding Renderer Globals
-----------------------
-Whenever :app:`Pyramid` handles a request to perform a rendering
-(after a view with a ``renderer=`` configuration attribute is invoked,
-or when the any of the methods beginning with ``render`` within the
-:mod:`pyramid.renderers` module are called), *renderer globals* can
-be injected into the *system* values sent to the renderer. By
-default, no renderer globals are injected, and the "bare" system
-values (such as ``request``, ``context``, and ``renderer_name``) are
-the only values present in the system dictionary passed to every
-renderer.
-
-A callback that :app:`Pyramid` will call every time a renderer is
-invoked can be added by passing a ``renderer_globals_factory``
-argument to the constructor of the :term:`configurator`. This
-callback can either be a callable object or a :term:`dotted Python
-name` representing such a callable.
+Whenever :app:`Pyramid` handles a request to perform a rendering (after a
+view with a ``renderer=`` configuration attribute is invoked, or when the any
+of the methods beginning with ``render`` within the :mod:`pyramid.renderers`
+module are called), *renderer globals* can be injected into the *system*
+values sent to the renderer. By default, no renderer globals are injected,
+and the "bare" system values (such as ``request``, ``context``, and
+``renderer_name``) are the only values present in the system dictionary
+passed to every renderer.
+
+A callback that :app:`Pyramid` will call every time a renderer is invoked can
+be added by passing a ``renderer_globals_factory`` argument to the
+constructor of the :term:`configurator`. This callback can either be a
+callable object or a :term:`dotted Python name` representing such a callable.
.. code-block:: python
:linenos:
@@ -411,30 +357,15 @@ name` representing such a callable.
config = Configurator(
renderer_globals_factory=renderer_globals_factory)
-Such a callback must accept a single positional argument (notionally
-named ``system``) which will contain the original system values. It
-must return a dictionary of values that will be merged into the system
-dictionary. See :ref:`renderer_system_values` for discription of the
-values present in the system dictionary.
+Such a callback must accept a single positional argument (notionally named
+``system``) which will contain the original system values. It must return a
+dictionary of values that will be merged into the system dictionary. See
+:ref:`renderer_system_values` for discription of the values present in the
+system dictionary.
-A renderer globals factory can alternately be registered via ZCML as a
-through the use of the ZCML ``utility`` directive. In the below, we
-assume a ``renderers_globals_factory`` function lives in a package
-named ``mypackage.mymodule``.
-
-.. code-block:: xml
- :linenos:
-
- <utility
- component="mypackage.mymodule.renderer_globals_factory"
- provides="pyramid.interfaces.IRendererGlobalsFactory"
- />
-
-Lastly, if you're doing imperative configuration, and you'd rather do
-it after you've already constructed a :term:`configurator` it can also
-be registered via the
-:meth:`pyramid.config.Configurator.set_renderer_globals_factory`
-method:
+If you're doing imperative configuration, and you'd rather do it after you've
+already constructed a :term:`configurator` it can also be registered via the
+:meth:`pyramid.config.Configurator.set_renderer_globals_factory` method:
.. code-block:: python
:linenos:
@@ -450,6 +381,9 @@ method:
Another mechanism which allows event subscribers to add renderer global values
exists in :ref:`beforerender_event`.
+If you'd rather ZCML to register a renderer globals factory, see
+:ref:`adding_renderer_globals_zcml`.
+
.. _beforerender_event:
Using The Before Render Event
@@ -472,8 +406,8 @@ that can be used for this purpose. For example:
An object of this type is sent as an event just before a :term:`renderer` is
invoked (but *after* the application-level renderer globals factory added via
-:class:`pyramid.config.Configurator.set_renderer_globals_factory`, if
-any, has injected its own keys into the renderer globals dictionary).
+:class:`pyramid.config.Configurator.set_renderer_globals_factory`, if any,
+has injected its own keys into the renderer globals dictionary).
If a subscriber attempts to add a key that already exist in the renderer
globals dictionary, a :exc:`KeyError` is raised. This limitation is enforced
@@ -493,16 +427,16 @@ renderer global values exists in :ref:`adding_renderer_globals`.
Using Response Callbacks
------------------------
-Unlike many other web frameworks, :app:`Pyramid` does not eagerly
-create a global response object. Adding a :term:`response callback`
-allows an application to register an action to be performed against a
-response object once it is created, usually in order to mutate it.
+Unlike many other web frameworks, :app:`Pyramid` does not eagerly create a
+global response object. Adding a :term:`response callback` allows an
+application to register an action to be performed against a response object
+once it is created, usually in order to mutate it.
-The :meth:`pyramid.request.Request.add_response_callback` method is
-used to register a response callback.
+The :meth:`pyramid.request.Request.add_response_callback` method is used to
+register a response callback.
-A response callback is a callable which accepts two positional
-parameters: ``request`` and ``response``. For example:
+A response callback is a callable which accepts two positional parameters:
+``request`` and ``response``. For example:
.. code-block:: python
:linenos:
@@ -515,11 +449,11 @@ parameters: ``request`` and ``response``. For example:
No response callback is called if an unhandled exception happens in
application code, or if the response object returned by a :term:`view
-callable` is invalid. Response callbacks *are*, however, invoked when
-a :term:`exception view` is rendered successfully: in such a case, the
-:attr:`request.exception` attribute of the request when it enters a
-response callback will be an exception object instead of its default
-value of ``None``.
+callable` is invalid. Response callbacks *are*, however, invoked when a
+:term:`exception view` is rendered successfully: in such a case, the
+:attr:`request.exception` attribute of the request when it enters a response
+callback will be an exception object instead of its default value of
+``None``.
Response callbacks are called in the order they're added
(first-to-most-recently-added). All response callbacks are called *after*
@@ -537,13 +471,13 @@ of a :class:`pyramid.events.NewRequest` event).
Using Finished Callbacks
------------------------
-A :term:`finished callback` is a function that will be called
-unconditionally by the :app:`Pyramid` :term:`router` at the very
-end of request processing. A finished callback can be used to perform
-an action at the end of a request unconditionally.
+A :term:`finished callback` is a function that will be called unconditionally
+by the :app:`Pyramid` :term:`router` at the very end of request processing.
+A finished callback can be used to perform an action at the end of a request
+unconditionally.
-The :meth:`pyramid.request.Request.add_finished_callback` method is
-used to register a finished callback.
+The :meth:`pyramid.request.Request.add_finished_callback` method is used to
+register a finished callback.
A finished callback is a callable which accepts a single positional
parameter: ``request``. For example:
@@ -563,25 +497,24 @@ parameter: ``request``. For example:
Finished callbacks are called in the order they're added ( first- to
most-recently- added). Finished callbacks (unlike a :term:`response
-callback`) are *always* called, even if an exception happens in
-application code that prevents a response from being generated.
-
-The set of finished callbacks associated with a request are called
-*very late* in the processing of that request; they are essentially
-the very last thing called by the :term:`router` before a request
-"ends". They are called after response processing has already occurred
-in a top-level ``finally:`` block within the router request processing
-code. As a result, mutations performed to the ``request`` provided to
-a finished callback will have no meaningful effect, because response
-processing will have already occurred, and the request's scope will
-expire almost immediately after all finished callbacks have been
-processed.
+callback`) are *always* called, even if an exception happens in application
+code that prevents a response from being generated.
+
+The set of finished callbacks associated with a request are called *very
+late* in the processing of that request; they are essentially the very last
+thing called by the :term:`router` before a request "ends". They are called
+after response processing has already occurred in a top-level ``finally:``
+block within the router request processing code. As a result, mutations
+performed to the ``request`` provided to a finished callback will have no
+meaningful effect, because response processing will have already occurred,
+and the request's scope will expire almost immediately after all finished
+callbacks have been processed.
It is often necessary to tell whether an exception occurred within
-:term:`view callable` code from within a finished callback: in such a
-case, the :attr:`request.exception` attribute of the request when it
-enters a response callback will be an exception object instead of its
-default value of ``None``.
+:term:`view callable` code from within a finished callback: in such a case,
+the :attr:`request.exception` attribute of the request when it enters a
+response callback will be an exception object instead of its default value of
+``None``.
Errors raised by finished callbacks are not handled specially. They
will be propagated to the caller of the :app:`Pyramid` router
@@ -598,22 +531,21 @@ Registering Configuration Decorators
------------------------------------
Decorators such as :class:`pyramid.view.view_config` don't change the
-behavior of the functions or classes they're decorating. Instead,
-when a :term:`scan` is performed, a modified version of the function
-or class is registered with :app:`Pyramid`.
-
-You may wish to have your own decorators that offer such
-behaviour. This is possible by using the :term:`Venusian` package in
-the same way that it is used by :app:`Pyramid`.
-
-By way of example, let's suppose you want to write a decorator that
-registers the function it wraps with a :term:`Zope Component
-Architecture` "utility" within the :term:`application registry`
-provided by :app:`Pyramid`. The application registry and the
-utility inside the registry is likely only to be available once your
-application's configuration is at least partially completed. A normal
-decorator would fail as it would be executed before the configuration
-had even begun.
+behavior of the functions or classes they're decorating. Instead, when a
+:term:`scan` is performed, a modified version of the function or class is
+registered with :app:`Pyramid`.
+
+You may wish to have your own decorators that offer such behaviour. This is
+possible by using the :term:`Venusian` package in the same way that it is
+used by :app:`Pyramid`.
+
+By way of example, let's suppose you want to write a decorator that registers
+the function it wraps with a :term:`Zope Component Architecture` "utility"
+within the :term:`application registry` provided by :app:`Pyramid`. The
+application registry and the utility inside the registry is likely only to be
+available once your application's configuration is at least partially
+completed. A normal decorator would fail as it would be executed before the
+configuration had even begun.
However, using :term:`Venusian`, the decorator could be written as
follows: