diff options
| -rw-r--r-- | CHANGES.txt | 4 | ||||
| -rw-r--r-- | docs/glossary.rst | 10 | ||||
| -rw-r--r-- | docs/narr/configuration.rst | 28 | ||||
| -rw-r--r-- | docs/narr/environment.rst | 12 | ||||
| -rw-r--r-- | docs/narr/events.rst | 114 | ||||
| -rw-r--r-- | docs/narr/views.rst | 30 | ||||
| -rw-r--r-- | docs/tutorials/cmf/skins.rst | 5 | ||||
| -rw-r--r-- | repoze/bfg/configuration.py | 5 |
8 files changed, 50 insertions, 158 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 9150847f3..3c048a45e 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -15,6 +15,10 @@ Documentation configuration into account in more places and uses glossary references more liberally. +- 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. + 1.2a4 (2009-12-07) ================== diff --git a/docs/glossary.rst b/docs/glossary.rst index 6ee6dc80b..491ad6d48 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -377,12 +377,10 @@ Glossary Request type An attribute of a :term:`request` that allows for specialization of view invocation based on arbitrary categorization. The every - :term:`request` object that bfg generates and manipulates has one - or more :term:`interface` objects attached to it. The default - interface attached to a request object is - ``repoze.bfg.interfaces.IRequest``. See - :ref:`using_an_event_to_vary_the_request_type` for more - information. + :term:`request` object that :mod:`repoze.bfg` generates and + manipulates has one or more :term:`interface` objects attached to + it. The default interface attached to a request object is + ``repoze.bfg.interfaces.IRequest``. repoze.lemonade Zope2 CMF-like `data structures and helper facilities <http://docs.repoze.org/lemonade>`_ for CA-and-ZODB-based diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index 7479086a5..98b3f221e 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -193,25 +193,18 @@ based on a URL. However, our sample application uses only :term:`traversal`. In :mod:`repoze.bfg` terms, :term:`traversal` is the act of walking -over a *directed graph* of objects from a :term:`root` object using -the individual path segments of the "path info" portion of a URL (the -data following the hostname and port number, but before any query -string elements or fragments, for example the ``/a/b/c`` portion of -the URL ``http://example.com/a/b/c?foo=1``) in order to find a -:term:`context` object and a :term:`view name`. The combination of -the :term:`context` object and the :term:`view name` (and, in more -complex configurations, other :term:`predicate` values) are used to -find "the right" :term:`view callable`, which will be invoked after +over an object graph starting from a :term:`root` object in order to +find a :term:`context` object and a :term:`view name`. The individual +path segments of the "path info" portion of a URL (the data following +the hostname and port number, but before any query string elements or +fragments, for example the ``/a/b/c`` portion of the URL +``http://example.com/a/b/c?foo=1``) are used as "steps" during traversal. .. note:: A useful analogy of how :mod:`repoze.bfg` :term:`traversal` works is available within the section entitled :ref:`traversal_behavior`. You should probably go read it now. -The object graph of our hello world application is very simple: -there's exactly one object in our graph; the default :term:`root` -object. - The results of a :term:`traversal` include a :term:`context` and a :term:`view name`. The :term:`view name` is the *first* URL path segment in the set of path segments "left over" during @@ -231,6 +224,15 @@ exhausting all the path segments implied by the path info of the URL: no segments are "left over". In this case, because the :term:`view name` is non-empty, a *non-default* view callable will be invoked. +The combination of the :term:`context` object and the :term:`view +name` (and, in more complex configurations, other :term:`predicate` +values) are used to find "the right" :term:`view callable`, which will +be invoked after traversal. + +The object graph of our hello world application is very simple: +there's exactly one object in our graph; the default :term:`root` +object. + Apologies for the digression; on with the tutorial. Relating Traversal to the Hello World Application diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 7163eff71..5f3dc345c 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -1,7 +1,7 @@ .. _environment_chapter: -Environment and Configuration -============================= +Environment Variables and ``.ini`` File Settings +================================================ :mod:`repoze.bfg` behavior can be configured through a combination of operating system environment variables and ``.ini`` configuration file @@ -47,16 +47,16 @@ application-specific configuration settings. | ``BFG_RELOAD_ALL`` | ``reload_all`` | Turns all reload_* settings on. | +---------------------------------+-----------------------------+----------------------------------------+ | ``BFG_CONFIGURE_ZCML`` | ``configure_zcml`` | Use the specified filename to load | -| | | the :term:`application registry` | +| | | the default app :term:`ZCML` file | | | | instead of the filename implied by | | | | ``filename`` value passed to | -| | | ``repoze.bfg.router.make_app``. If | +| | | ``repoze.bfg.router.make_app``. If | | | | this is a relative filename, it will | | | | be considered relative to the | | | | ``package`` passed to ``make_app`` | | | | by the application. It may also | -| | | take the form of a resource | -| | | "specification" which names both the | +| | | take the form of a :term:`resource | +| | | specification` which names both the | | | | package name and a package-relative | | | | filename, e.g. | | | | ``dotted.package.name:path/to.zcml``. | 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. diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 181a295b5..913f5cd88 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -461,14 +461,13 @@ request_type This value should be a Python dotted-path string representing the :term:`interface` that the :term:`request` must have in order for - this view to be found and called. See - :ref:`view_request_types_section` for more information about request - types. For backwards compatibility with :mod:`repoze.bfg` version - 1.0, this value may also be an HTTP ``REQUEST_METHOD`` string, e.g. - ('GET', 'HEAD', 'PUT', 'POST', or 'DELETE'). Passing request method - strings as a ``request_type`` is deprecated. Use the - ``request_method`` attribute instead for maximum forward - compatibility. + this view to be found and called. The presence of this attribute is + largely for backwards compatibility with applications written for + :mod:`repoze.bfg` version 1.0. This value may be an HTTP + ``REQUEST_METHOD`` string, e.g. ('GET', 'HEAD', 'PUT', 'POST', or + 'DELETE'). Passing request method strings as a ``request_type`` is + deprecated. Use the ``request_method`` attribute instead for + maximum forward compatibility. request_method @@ -1554,21 +1553,6 @@ rendered in a request that has a ``;charset=utf-8`` stanza on its to Unicode objects implicitly in :mod:`repoze.bfg`'s default configuration. The keys are still strings. -.. _view_request_types_section: - -Custom View Request Types -------------------------- - -You can make use of *custom* view request types by attaching an -:term:`interface` to the request and specifying this interface in the -``request_type`` parameter as a dotted Python name. For example, you -might want to make use of simple "content negotiation", only invoking -a particular view if the request has a content-type of -'application/json'. - -For information about using interface to specify a request type, see -:ref:`using_an_event_to_vary_the_request_type`. - .. _response_request_attrs: Varying Attributes of Rendered Responses diff --git a/docs/tutorials/cmf/skins.rst b/docs/tutorials/cmf/skins.rst index 549fb4621..5f5c2c447 100644 --- a/docs/tutorials/cmf/skins.rst +++ b/docs/tutorials/cmf/skins.rst @@ -18,9 +18,8 @@ for more information about resource overrides. While there is no analogue to a skin layer search path for locating Python code (as opposed to resources), :term:`view` code combined with -differing :term:`request type` attributes can provide a good deal of -the same sort of behavior. See -:ref:`using_an_event_to_vary_the_request_type` for more information. +differing :term:`predicate` arguments can provide a good deal of +the same sort of behavior. Relatedly, the `repoze.bfg.skins <http://svn.repoze.org/repoze.bfg.skins/>`_ package is an attempt to diff --git a/repoze/bfg/configuration.py b/repoze/bfg/configuration.py index 6cb4feb8d..74d91a73b 100644 --- a/repoze/bfg/configuration.py +++ b/repoze/bfg/configuration.py @@ -470,8 +470,9 @@ class Configurator(object): This value should be an :term:`interface` that the :term:`request` must provide in order for this view to be - found and called. See :ref:`view_request_types_section` for - more information about request types. + found and called. This value exists only for backwards + compatibility purposes: it's usually easier to use another + predicate. request_method |
