diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-12-09 16:54:43 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-12-09 16:54:43 +0000 |
| commit | e40eb200171e5917c4a8b7419127ae3e7b2af0ab (patch) | |
| tree | c070dca104606cceadea1924ae2de158d61111fa /docs/narr/events.rst | |
| parent | 42da8fe9f779c5bcd7694348a1b47f5ec2bc5e59 (diff) | |
| download | pyramid-e40eb200171e5917c4a8b7419127ae3e7b2af0ab.tar.gz pyramid-e40eb200171e5917c4a8b7419127ae3e7b2af0ab.tar.bz2 pyramid-e40eb200171e5917c4a8b7419127ae3e7b2af0ab.zip | |
- Remove explanation of changing the request type in a new request
event subscriber, as other predicates are now usually an easier way
to get this done.
Diffstat (limited to 'docs/narr/events.rst')
| -rw-r--r-- | docs/narr/events.rst | 114 |
1 files changed, 9 insertions, 105 deletions
diff --git a/docs/narr/events.rst b/docs/narr/events.rst index cd5a94871..c70494195 100644 --- a/docs/narr/events.rst +++ b/docs/narr/events.rst @@ -4,12 +4,12 @@ Using Events ============= An *event* is an object broadcast by the :mod:`repoze.bfg` framework -at particularly interesting points during the lifetime of an -application. You don't need to use, know about, or care about events -in order to create most :mod:`repoze.bfg` applications, but they can -be useful when you want to perform slightly advanced operations. For -example, subscribing to an event can allow you to "skin" a site -slightly differently based on the hostname used to reach the site. +at interesting points during the lifetime of an application. You +don't need to use, know about, or care about events in order to create +most :mod:`repoze.bfg` applications, but they can be useful when you +want to perform slightly advanced operations. For example, +subscribing to an event can allow you to "skin" a site slightly +differently based on the hostname used to reach the site. Events in :mod:`repoze.bfg` are always broadcast by the framework. However, they only become useful when you register a *subscriber*. A @@ -145,108 +145,12 @@ which is a :term:`WebOb` request, because the interface defined at ``repoze.bfg.interfaces.INewRequest`` says it must. Likewise, we know that ``INewResponse`` events have a ``response`` attribute, which is a response object constructed by your application, because the interface -defined at ``repoze.bfg.interfaces.INewResponse`` says it must. These -particular interfaces, along with others, are documented in the -:ref:`events_module` API chapter. +defined at ``repoze.bfg.interfaces.INewResponse`` says it must. The return value of a subscriber function is ignored. Subscribers to the same event type are not guaranteed to be called in any particular order relative to one another. -.. _using_an_event_to_vary_the_request_type: - -Using An Event to Vary the Request Type ---------------------------------------- - -The most common usage of the ``INewRequestEvent`` is to attach an -:term:`interface` to a request after introspecting the request data in -some way. For example, you might want to be able to differentiate a -request issued by a browser from a request issued by a JSON client. -This differentiation makes it possible to register different views -against different ``request_type`` interfaces; for instance, depending -on the presence of a request header, you might return JSON data. - -To do this, you should subscribe an function to the ``INewRequest`` -event type, and you should use the ``zope.interface.alsoProvides`` API -within the function to add one or more interfaces to the request -object provided by the event. Here's an example. - -.. code-block:: python - :linenos: - - from zope.interface import alsoProvides - from zope.interface import Interface - - class IJSONRequest(Interface): - """ A request from a JSON client that sets and Accept: - application/json header """ - - def categorize_request(event): - request = event.request - accept = request.headers.get('accept', '') - if 'application/json' in accept: - alsoProvides(request, IJSONRequest) - -If you subscribe ``categorize_request`` for the -``repoze.bfg.interfaces.INewRequest`` type, the ``IJSONRequest`` -interface will be attached to each request object that has ``accept`` -headers which match ``application/json``. - -Thereafter, you can use the ``request_type`` attribute of a -term:`view` ZCML statement or a ``@bfg_view`` decorator to refer to -this ``IJSONRequest`` interface. For example: - -.. code-block:: xml - :linenos: - - <subscriber - for="repoze.bfg.interfaces.INewRequest" - handler=".subscribers.categorize_request" - /> - - <!-- html default view --> - <view - for=".models.MyModel" - view=".views.html_view"/> - - <!-- JSON default view --> - <view - for=".models.MyModel" - request_type=".interfaces.IJSONRequest" - view=".views.json_view"/> - -The interface ``repoze.bfg.interfaces.IRequest`` is automatically -implemented by every :mod:`repoze.bfg` request. Views which do not -supply a ``request_type`` attribute will be considered to be -registered for ``repoze.bfg.interfaces.IRequest`` as a default. But -in the example above, ``.views.json_view`` will be called when a -request supplies our ``IJSONRequest`` interface, because it is a more -specific interface. - -Of course, you are not limited to using the ``Accept`` header to -determine which interface to attach to a request within an event -subscriber. For example, you might also choose to introspect the -hostname (e.g. ``request.environ.get('HTTP_HOST', -request.environ['SERVER_NAME'])``) in order to "skin" your application -differently based on whether the user should see the "management" -(e.g. "manage.myapp.com") presentation of the application or the -"retail" presentation (e.g. "www.myapp.com"). - -By attaching to the request an arbitrary interface after examining the -hostname or any other information available in the request within an -``INewRequest`` event subscriber, you can control view lookup -precisely. For example, if you wanted to have two slightly different -views for requests to two different hostnames, you might register one -view with a ``request_type`` of ``.interfaces.IHostnameFoo`` and -another with a ``request_type`` of ``.interfaces.IHostnameBar`` and -then arrange for an event subscriber to attach -``.interfaces.IHostnameFoo`` to the request when the HTTP_HOST is -``foo`` and ``.interfaces.IHostnameBar`` to the request when the -HTTP_HOST is ``bar``. The appropriate view will be called. - -You can also form an inheritance hierarchy out of ``request_type`` -interfaces. When :mod:`repoze.bfg` looks up a view, the most specific -view for the interface(s) found on the request based on standard -Python method resolution order through the interface class hierarchy -will be called. +All other concrete event types are documented in the +:ref:`events_module` API chapter. |
