diff options
Diffstat (limited to 'docs/narr/hooks.rst')
| -rw-r--r-- | docs/narr/hooks.rst | 125 |
1 files changed, 99 insertions, 26 deletions
diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 2917b5254..b3b41046f 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -70,9 +70,6 @@ Here's some sample code that implements a minimal NotFound view 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 @@ -83,7 +80,7 @@ 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 default forbidden response has a 403 status code and is very plain, but the view which generates it can be overridden as necessary. The :term:`forbidden view` callable is a view callable like any other. The @@ -132,15 +129,6 @@ Here's some sample code that implements a minimal forbidden view: ``debug_authorization`` environment setting is true than it is when it is false. -.. warning:: the default forbidden view sends a response with a ``401 - Unauthorized`` status code for backwards compatibility reasons. - You can influence the status code of Forbidden responses by using - 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: request factory @@ -185,8 +173,6 @@ already constructed a :term:`configurator` it can also be registered via the config = Configurator() config.set_request_factory(MyRequest) -To use ZCML for the same purpose, see :ref:`changing_request_factory_zcml`. - .. index:: single: renderer globals @@ -242,9 +228,6 @@ already constructed a :term:`configurator` it can also be registered via the 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`. - .. index:: single: before render event @@ -365,10 +348,11 @@ parameter: ``request``. For example: transaction.commit() request.add_finished_callback(commit_callback) -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. +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 @@ -474,9 +458,6 @@ 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 @@ -541,6 +522,98 @@ The default context URL generator is available for perusal as the class :term:`Pylons` GitHub Pyramid repository. .. index:: + single: view mapper + +.. _using_a_view_mapper: + +Using a View Mapper +------------------- + +The default calling conventions for view callables are documented in the +:ref:`views_chapter` chapter. You can change the way users define view +callbles by employing a :term:`view mapper`. + +A view mapper is an object that accepts a set of keyword arguments and which +returns a callable. The returned callable is called with the :term:`view +callable` object. The returned callable should itself return another +callable which can be called with the "internal calling protocol" ``(context, +request)``. + +You can use a view mapper in a number of ways: + +- by setting a ``__view_mapper__`` attribute (which is the view mapper + object) on the view callable itself + +- by passing the mapper object to + :meth:`pyramid.config.Configurator.add_view` (or its declarative/decorator + equivalents) as the ``mapper`` argument. + +- by registering a *default* view mapper. + +Here's an example of a view mapper that emulates (somewhat) a Pylons +"controller". The mapper is initialized with some keyword arguments. Its +``__call__`` method accepts the view object (which will be a class). It uses +the ``attr`` keyword argument it is passed to determine which attribute +should be used as an action method. The wrapper method it returns accepts +``(context, request)`` and returns the result of calling the action method +with keyword arguments implied by the :term:`matchdict` after popping the +``action`` out of it. This somewhat emulates the Pylons style of calling +action methods with routing parameters pulled out of the route matching dict +as keyword arguments. + +.. code-block:: python + :linenos: + + # framework + + class PylonsControllerViewMapper(object): + def __init__(self, **kw): + self.kw = kw + + def __call__(self, view): + attr = self.kw['attr'] + def wrapper(context, request): + matchdict = request.matchdict.copy() + matchdict.pop('action', None) + inst = view() + meth = getattr(inst, attr) + return meth(**matchdict) + return wrapper + + class BaseController(object): + __view_mapper__ = PylonsControllerViewMapper + +A user might make use of these framework components like so: + +.. code-block:: python + :linenos: + + # user application + + from webob import Response + from pyramid.config import Configurator + import pyramid_handlers + from paste.httpserver import serve + + class MyController(BaseController): + def index(self, id): + return Response(id) + + if __name__ == '__main__': + config = Configurator() + config.include(pyramid_handlers) + config.add_handler('one', '/{id}', MyController, action='index') + config.add_handler('two', '/{action}/{id}', MyController) + serve(config.make_wsgi_app()) + +The :meth:`pyramid.config.Configurator.set_default_mapper` method can be used +to set a *default* view mapper (overriding the superdefault view mapper used +by Pyramid itself). + +A *single* view registration can use a view mapper by passing the mapper as +the ``mapper`` argument to :meth:`pyramid.config.Configuration.add_view`. + +.. index:: single: configuration decorator .. _registering_configuration_decorators: @@ -581,7 +654,7 @@ follows: self.path = path def register(self, scanner, name, wrapped): - registry = get_current_registry() + registry = scanner.config.registry registry.getUtility(IMyUtility).register( self.path, wrapped ) |
