diff options
| author | Chris McDonough <chrism@plope.com> | 2010-12-19 18:40:05 -0500 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2010-12-19 18:40:05 -0500 |
| commit | 53f1bb24eb51ac994185f2365930220a9d87e77e (patch) | |
| tree | 369fa30db6e75f67e3204038196f8515097393f7 /docs | |
| parent | a59c789b2bb4a1de5f79537cc2f1022c97bb51f6 (diff) | |
| download | pyramid-53f1bb24eb51ac994185f2365930220a9d87e77e.tar.gz pyramid-53f1bb24eb51ac994185f2365930220a9d87e77e.tar.bz2 pyramid-53f1bb24eb51ac994185f2365930220a9d87e77e.zip | |
merge handlers chapter into views chapter
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/index.rst | 1 | ||||
| -rw-r--r-- | docs/latexindex.rst | 1 | ||||
| -rw-r--r-- | docs/narr/handlers.rst | 243 | ||||
| -rw-r--r-- | docs/narr/views.rst | 262 |
4 files changed, 252 insertions, 255 deletions
diff --git a/docs/index.rst b/docs/index.rst index 9cfcddebe..8c37f8faa 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -43,7 +43,6 @@ Narrative documentation in chapter form explaining how to use narr/traversal narr/views narr/renderers - narr/handlers narr/hybrid narr/static narr/webob diff --git a/docs/latexindex.rst b/docs/latexindex.rst index d4fec36d8..77afdf949 100644 --- a/docs/latexindex.rst +++ b/docs/latexindex.rst @@ -36,7 +36,6 @@ Narrative Documentation narr/traversal narr/views narr/renderers - narr/handlers narr/hybrid narr/static narr/webob diff --git a/docs/narr/handlers.rst b/docs/narr/handlers.rst deleted file mode 100644 index 5b6f71984..000000000 --- a/docs/narr/handlers.rst +++ /dev/null @@ -1,243 +0,0 @@ -.. _handlers_chapter: - -View Handlers -============= - -Along with normal view callables, :app:`Pyramid` provides the concept of a -:term:`view handler`. Using a view handler instead of a plain :term:`view -callable` makes it unnecessary to call -:meth:`pyramid.config.Configurator.add_route` (and/or -:meth:`pyramid.config.Configurator.add_view`) "by hand" multiple -times, making it more pleasant to register a collection of views as a single -class when using :term:`url dispatch`. The view handler machinery also -introduces the concept of an ``action``, which is used as a :term:`view -predicate` to control which method of the handler is called. - -.. note:: - - View handlers are not useful when using :term:`traversal`, only when using - :term:`url dispatch`. The concept of a view handler is analogous to a - "controller" in Pylons 1.0. - -The view handler class is initialized by :app:`Pyramid` in the same -manner as a view class. Its ``__init__`` is called with a request -object (see :ref:`class_as_view`) as its argument when a request enters -the system which corresponds with a view handler registration made -during configuration. After the view handler class is instantiated, a -method on the instance is called. The method which is called depends on -the view handler configuration. - -The :meth:`pyramid.config.Configurator.add_handler` method will -scan the handler class and automatically set up views for methods that -are auto-exposed, or were decorated with the -:class:`~pyramid.view.action` decorator. This decorator is used to setup -additional view configuration information for individual methods of the -class, and can be used repeatedly for a single view method to -register multiple view configurations for it. - -Here's an example view handler class: - -.. code-block:: python - :linenos: - - from pyramid.response import Response - - from pyramid.view import action - - class Hello(object): - def __init__(self, request): - self.request = request - - def index(self): - return Response('Hello world!') - - @action(renderer="mytemplate.mak") - def bye(self): - return {} - -An accompanying call to the -:meth:`~pyramid.config.Configurator.add_handler` for the handler must -be performed in order to register it with the system: - -.. code-block:: python - :linenos: - - config.add_handler('hello', '/hello/{action}', handler=Hello) - -This example will result in a route being added for the pattern -``/hello/{action}``, each method of the ``Hello`` class will then be examined -to register the views. The value of ``{action}`` in the route pattern will be -used to determine which view should be called, and each view in the class will -be setup with a view predicate that requires a specific ``action`` name. - -If the URL in the above example was ``/hello/index``, then the ``index`` -method of the Hello class would be called. - -Alternatively, the action can be declared specifically for a URL to go to a -specific ``action`` name: - -.. code-block:: python - :linenos: - - config.add_handler('hello_index', '/hello/index', - handler=Hello, action='index') - -This will result one of the methods that are configured for the ``action`` of -'index' in the ``Hello`` handler class to be called. In this case the name -of the method is the same as the action name: 'index'. However, this -need not be the case, as we will see below. - -.. note:: - - Handler configuration may also be added to the system via :term:`ZCML` (see - :ref:`zcml_handler_configuration`). - -.. _using_add_handler: - -Using :meth:`~pyramid.config.Configurator.add_handler` -------------------------------------------------------------- - -When calling :meth:`~pyramid.config.Configurator.add_handler`, an -``action`` is required in either the route pattern or as a keyword argument, -but **cannot appear in both places**. A ``handler`` argument must also be -supplied, which can be either a :term:`asset specification` or a Python -reference to the handler class. Additional keyword arguments are passed -directly through to :meth:`pyramid.config.Configurator.add_route`. - -For example: - -.. code-block:: python - :linenos: - - config.add_handler('hello', '/hello/{action}', - handler='mypackage.handlers:MyHandler') - -In larger applications, it is advised to use a :term:`asset specification` -with :meth:`~pyramid.config.Configurator.add_handler` to avoid having -to import every handler class. - -Multiple :meth:`~pyramid.config.Configurator.add_handler` calls can -specify the same handler, to register specific route names for different -handler/action combinations. For example: - -.. code-block:: python - :linenos: - - config.add_handler('hello_index', '/hello/index', - handler=Hello, action='index') - config.add_handler('bye_index', '/hello/bye', - handler=Hello, action='bye') - - -View Setup in the Handler Class -------------------------------- - -The handler class specified can have a single class level attribute called -``__autoexpose__`` which should be a regular expression or the value -``None``. It's used to determine which method names will result in additional -view configurations being registered. - -When :meth:`~pyramid.config.Configurator.add_handler` runs, every -method in the handler class will be searched and a view registered if the -method name matches the ``__autoexpose__`` regular expression, or if the -method was decorated with :class:`~pyramid.view.action`. - -Auto-exposed Views ------------------- - -Every method in the handler class that has a name meeting the -``_autoexpose__`` regular expression will have a view registered for an -``action`` name corresponding to the method name. This functionality can be -disabled by setting the ``__autoexpose__`` attribute to ``None``: - -.. code-block:: python - :linenos: - - from pyramid.view import action - - class Hello(object): - __autoexpose__ = None - - def __init__(self, request): - self.request = request - - @action() - def index(self): - return Response('Hello world!') - - @action(renderer="mytemplate.mak") - def bye(self): - return {} - -With auto-expose effectively disabled, no views will be registered for a -method unless it is specifically decorated with :class:`~pyramid.view.action`. - -Action Decorator ----------------- - -The :class:`~pyramid.view.action` decorator registers view configuration -information on the handler method, which is used by -:meth:`~pyramid.config.Configurator.add_handler` to setup the view -configuration. - -All keyword arguments are recorded, and passed to -:meth:`~pyramid.config.Configurator.add_view`. Any valid keyword -arguments for :meth:`~pyramid.config.Configurator.add_view` can thus be -used with the :class:`~pyramid.view.action` decorator to further restrict when -the view will be called. - -One important difference is that a handler method can respond to an ``action`` -name that is different from the method name by passing in a ``name`` argument. - -Example: - -.. code-block:: python - :linenos: - - from pyramid.view import action - - class Hello(object): - def __init__(self, request): - self.request = request - - @action(name='index', renderer='created.mak', request_method='POST') - def create(self): - return {} - - @action(renderer="view_all.mak", request_method='GET') - def index(self): - return {} - -This will register two views that require the ``action`` to be ``index``, with -the additional view predicate requiring a specific request method. - -It can be useful to decorate a single method multiple times with -:class:`~pyramid.view.action`. Each action decorator will register a new view -for the method. By specifying different names and renderers for each action, -the same view logic can be exposed and rendered differently on multiple -URLs. - -Example: - -.. code-block:: python - :linenos: - - from pyramid.view import action - - class Hello(object): - def __init__(self, request): - self.request = request - - @action(name='home', renderer='home.mak') - @action(name='about', renderer='about.mak') - def show_template(self): - # prep some template vars - return {} - - # in the config - config.add_handler('hello', '/hello/{action}', handler=Hello) - -With this configuration, the url ``/hello/home`` will find a view configuration -that results in calling the ``show_template`` method, then rendering the -template with ``home.mak``, and the url ``/hello/about`` will call the same -method and render the ``about.mak`` template. diff --git a/docs/narr/views.rst b/docs/narr/views.rst index c66da636f..447385458 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -198,6 +198,58 @@ related view callables. No matter which view calling convention is used, the view code always has access to the context via ``request.context``. +Defining a Set of View Callables Using a Handler +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Along with normal view callable functions, instances, and classes, +:app:`Pyramid` provides the special concept of a :term:`view handler`. View +handlers are a convenience for :term:`URL dispatch` users. The concept of a +view handler is analogous to a "controller" in Pylons 1.0. Using a view +handler instead of a plain function or class :term:`view callable` makes it +unnecessary to call :meth:`pyramid.config.Configurator.add_route` (and/or +:meth:`pyramid.config.Configurator.add_view`) "by hand" multiple times, +making it more pleasant to register a collection of views as a single class +when using :term:`url dispatch`. The view handler machinery also introduces +the concept of an ``action``, which is used as a :term:`view predicate` to +control which method of the handler is called. + +.. note:: + + View handlers are *not* useful when using :term:`traversal`, only when using + :term:`url dispatch`. + +The view handler class is initialized by :app:`Pyramid` in the same manner as +a view *class*. Its ``__init__`` is called with a request object (see +:ref:`class_as_view`) as its argument when a request enters the system which +corresponds with a view handler registration made during configuration. +After the view handler class is instantiated, a method on the instance is +called. Typically, each method of the handler is used as a view callable. +The methods which are called depends on the view handler's configuration. + +Here's an example view handler class: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + + from pyramid.view import action + + class Hello(object): + def __init__(self, request): + self.request = request + + def index(self): + return Response('Hello world!') + + @action(renderer="mytemplate.mak") + def bye(self): + return {} + +Handlers are added to application configuration via the +:meth:`pyramid.config.Configurator.add_handler` API, as described in +:ref:`using_add_handler`. + .. index:: single: view response single: response @@ -524,8 +576,8 @@ using your own response object, you will need to ensure you do this yourself. .. _view_configuration: -View Configuration: Mapping a Resource Type to a View ------------------------------------------------------ +View Configuration: Mapping a Resource or URL Pattern to a View Callable +------------------------------------------------------------------------ A developer makes a :term:`view callable` available for use within a :app:`Pyramid` application via :term:`view configuration`. A view @@ -547,16 +599,21 @@ View configuration is performed in one of these ways: :meth:`pyramid.config.Configurator.add_view` and :ref:`mapping_views_using_imperative_config_section`. -Both of these mechanisms is completely equivalent to the other. +- By specifying a view within a :term:`route configuration`. View + configuration via a route configuration is performed by using the + :meth:`pyramid.config.Configurator.add_route` method, passing a ``view`` + argument specifying a view callable. -.. note:: You can also add view configuration by adding a ``<view>`` - declaration to :term:`ZCML` used by your application as per - :ref:`mapping_views_using_zcml_section` and :ref:`view_directive`. +- by using the :meth:`pyramid.config.Configurator.add_handler` against a + :term:`view handler` class (useful only for :term:`URL dispatch` + applications). -A view configuration might also be performed by virtue of :term:`route -configuration`. View configuration via route configuration is performed by -using the :meth:`pyramid.config.Configurator.add_route` method to create a -route with a ``view`` argument. +.. note:: You can also add view configuration by adding a ``<view>`` or + ``<handler>`` declaration to :term:`ZCML` used by your application as per + :ref:`mapping_views_using_zcml_section`, :ref:`view_directive`, and + :ref:`handler_directive`. + +A view configuration might also be performed by virtue of .. note:: ZCML users can use :ref:`route_directive` to perform the same task. See also :ref:`zcml_route_configuration`. @@ -1055,6 +1112,191 @@ which is the view itself or a :term:`dotted Python name` to such an object. All other arguments are optional. See :meth:`pyramid.config.Configurator.add_view` for more information. +.. _using_add_handler: + +Using :meth:`~pyramid.config.Configurator.add_handler` to Register a Handler +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The :meth:`pyramid.config.Configurator.add_handler` method will scan a +:term:`view handler` class and automatically set up view configurations for +its methods that represent "auto-exposed" view callable, or those that were +decorated explicitly with the :class:`~pyramid.view.action` decorator. This +decorator is used to setup additional view configuration information for +individual methods of the class, and can be used repeatedly for a single view +method to register multiple view configurations for it. + +.. code-block:: python + :linenos: + + from myapp.handlers import Hello + config.add_handler('hello', '/hello/{action}', handler=Hello) + +This example will result in a route being added for the pattern +``/hello/{action}``, each method of the ``Hello`` class will then be examined +to register the views. The value of ``{action}`` in the route pattern will be +used to determine which view should be called, and each view in the class +will be setup with a view predicate that requires a specific ``action`` name. + +If the URL in the above example was ``/hello/index``, then the ``index`` +method of the Hello class would be called. + +Alternatively, the action can be declared specifically for a URL to go to a +specific ``action`` name: + +.. code-block:: python + :linenos: + + from myapp.handlers import Hello + config.add_handler('hello_index', '/hello/index', + handler=Hello, action='index') + +This will result one of the methods that are configured for the ``action`` of +'index' in the ``Hello`` handler class to be called. In this case the name of +the method is the same as the action name: 'index'. However, this need not be +the case, as we will see below. + +When calling :meth:`~pyramid.config.Configurator.add_handler`, an ``action`` +is required in either the route pattern or as a keyword argument, but +**cannot appear in both places**. A ``handler`` argument must also be +supplied, which can be either a :term:`asset specification` or a Python +reference to the handler class. Additional keyword arguments are passed +directly through to :meth:`pyramid.config.Configurator.add_route`. + +For example: + +.. code-block:: python + :linenos: + + config.add_handler('hello', '/hello/{action}', + handler='mypackage.handlers.MyHandler') + +Multiple :meth:`~pyramid.config.Configurator.add_handler` calls can specify +the same handler, to register specific route names for different +handler/action combinations. For example: + +.. code-block:: python + :linenos: + + config.add_handler('hello_index', '/hello/index', + handler=Hello, action='index') + config.add_handler('bye_index', '/hello/bye', + handler=Hello, action='bye') + +.. note:: + + Handler configuration may also be added to the system via :term:`ZCML` (see + :ref:`zcml_handler_configuration`). + +View Setup in the Handler Class ++++++++++++++++++++++++++++++++ + +The handler class specified can have a single class level attribute called +``__autoexpose__`` which should be a regular expression or the value +``None``. It's used to determine which method names will result in additional +view configurations being registered. + +When :meth:`~pyramid.config.Configurator.add_handler` runs, every +method in the handler class will be searched and a view registered if the +method name matches the ``__autoexpose__`` regular expression, or if the +method was decorated with :class:`~pyramid.view.action`. + +Every method in the handler class that has a name meeting the +``_autoexpose__`` regular expression will have a view registered for an +``action`` name corresponding to the method name. This functionality can be +disabled by setting the ``__autoexpose__`` attribute to ``None``: + +.. code-block:: python + :linenos: + + from pyramid.view import action + + class Hello(object): + __autoexpose__ = None + + def __init__(self, request): + self.request = request + + @action() + def index(self): + return Response('Hello world!') + + @action(renderer="mytemplate.mak") + def bye(self): + return {} + +With auto-expose effectively disabled, no views will be registered for a +method unless it is specifically decorated with :class:`~pyramid.view.action`. + +Action Decorators in a Handler +++++++++++++++++++++++++++++++ + +The :class:`~pyramid.view.action` decorator registers view configuration +information on the handler method, which is used by +:meth:`~pyramid.config.Configurator.add_handler` to setup the view +configuration. + +All keyword arguments are recorded, and passed to +:meth:`~pyramid.config.Configurator.add_view`. Any valid keyword arguments +for :meth:`~pyramid.config.Configurator.add_view` can thus be used with the +:class:`~pyramid.view.action` decorator to further restrict when the view +will be called. + +One important difference is that a handler method can respond to an +``action`` name that is different from the method name by passing in a +``name`` argument. + +Example: + +.. code-block:: python + :linenos: + + from pyramid.view import action + + class Hello(object): + def __init__(self, request): + self.request = request + + @action(name='index', renderer='created.mak', request_method='POST') + def create(self): + return {} + + @action(renderer="view_all.mak", request_method='GET') + def index(self): + return {} + +This will register two views that require the ``action`` to be ``index``, +with the additional view predicate requiring a specific request method. + +It can be useful to decorate a single method multiple times with +:class:`~pyramid.view.action`. Each action decorator will register a new view +for the method. By specifying different names and renderers for each action, +the same view logic can be exposed and rendered differently on multiple URLs. + +Example: + +.. code-block:: python + :linenos: + + from pyramid.view import action + + class Hello(object): + def __init__(self, request): + self.request = request + + @action(name='home', renderer='home.mak') + @action(name='about', renderer='about.mak') + def show_template(self): + # prep some template vars + return {} + + # in the config + config.add_handler('hello', '/hello/{action}', handler=Hello) + +With this configuration, the url ``/hello/home`` will find a view +configuration that results in calling the ``show_template`` method, then +rendering the template with ``home.mak``, and the url ``/hello/about`` will +call the same method and render the ``about.mak`` template. + .. index:: single: resource interfaces |
