From 8a1b50bc4027e25d5450cc6968f1f005af9d389f Mon Sep 17 00:00:00 2001 From: Casey Duncan Date: Sun, 2 Jan 2011 23:45:33 -0700 Subject: Split view chapter, move view config after templates, some reordering in view config --- docs/narr/viewconfig.rst | 965 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 965 insertions(+) create mode 100644 docs/narr/viewconfig.rst (limited to 'docs/narr/viewconfig.rst') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst new file mode 100644 index 000000000..39c0a0d1f --- /dev/null +++ b/docs/narr/viewconfig.rst @@ -0,0 +1,965 @@ +.. _view_config_chapter: + +.. _view_configuration: + +View Configuration +================== + +.. index:: + single: view lookup + +.. _view_lookup: + +View Lookup and Invocation +-------------------------- + +:term:`View lookup` is the :app:`Pyramid` subsystem responsible for finding +an invoking a :term:`view callable`. The view lookup subsystem is passed a +:term:`context` and a :term:`request` object. + +:term:`View configuration` information stored within in the +:term:`application registry` is compared against the context and request by +the view lookup subsystem in order to find the "best" view callable for the +set of circumstances implied by the context and request. + +:term:`View predicate` attributes are an important part of view +configuration that enables the :term:`View lookup` subsystem to find and +invoke the appropriate view. Predicate attributes can be thought of +like "narrowers". In general, the greater number of predicate +attributes possessed by a view's configuration, the more specific the +circumstances need to be before the registered view callable will be +invoked. + +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 +configuration associates a view callable with a set of statements that +determine the set of circumstances which must be true for the view callable +to be invoked. + +A view configuration statement is made about information present in the +:term:`context` resource and the :term:`request`. + +View configuration is performed in one of these ways: + +- by running a :term:`scan` against application source code which has a + :class:`pyramid.view.view_config` decorator attached to a Python object as + per :class:`pyramid.view.view_config` and + :ref:`mapping_views_using_a_decorator_section`. + +- by using the :meth:`pyramid.config.Configurator.add_view` method as per + :meth:`pyramid.config.Configurator.add_view` and + :ref:`mapping_views_using_imperative_config_section`. + +- 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. + +- by using the :meth:`pyramid.config.Configurator.add_handler` against a + :term:`view handler` class (useful only for :term:`URL dispatch` + applications). + +.. note:: You can also add view configuration by adding a ````, + ```` or ```` declaration to :term:`ZCML` used by your + application as per :ref:`mapping_views_using_zcml_section`, + :ref:`view_directive`, :ref:`route_directive` or :ref:`handler_directive`. + +.. _view_configuration_parameters: + +View Configuration Parameters +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +All forms of view configuration accept the same general types of arguments. + +Many arguments supplied during view configuration are :term:`view predicate` +arguments. View predicate arguments used during view configuration are used +to narrow the set of circumstances in which :mod:`view lookup` will find a +particular view callable. + +In general, the fewer number of predicates which are supplied to a +particular view configuration, the more likely it is that the associated +view callable will be invoked. The greater the number supplied, the +less likely. A view with five predicates will always be found and +evaluated before a view with two, for example. All predicates must +match for the associated view to be called. + +This does not mean however, that :app:`Pyramid` "stops looking" when it +finds a view registration with predicates that don't match. If one set +of view predicates does not match, the "next most specific" view (if +any) is consulted for predicates, and so on, until a view is found, or +no view can be matched up with the request. The first view with a set +of predicates all of which match the request environment will be +invoked. + +If no view can be found with predicates which allow it to be matched up with +the request, :app:`Pyramid` will return an error to the user's browser, +representing a "not found" (404) page. See :ref:`changing_the_notfound_view` +for more information about changing the default notfound view. + +Some view configuration arguments are non-predicate arguments. These tend to +modify the response of the view callable or prevent the view callable from +being invoked due to an authorization policy. The presence of non-predicate +arguments in a view configuration does not narrow the circumstances in which +the view callable will be invoked. + +Non-Predicate Arguments ++++++++++++++++++++++++ + +``permission`` + The name of a :term:`permission` that the user must possess in order to + invoke the :term:`view callable`. See :ref:`view_security_section` for + more information about view security and permissions. + + If ``permission`` is not supplied, no permission is registered for this + view (it's accessible by any caller). + +``attr`` + The view machinery defaults to using the ``__call__`` method of the + :term:`view callable` (or the function itself, if the view callable is a + function) to obtain a response. The ``attr`` value allows you to vary the + method attribute used to obtain the response. For example, if your view + was a class, and the class has a method named ``index`` and you wanted to + use this method instead of the class' ``__call__`` method to return the + response, you'd say ``attr="index"`` in the view configuration for the + view. This is most useful when the view definition is a class. + + If ``attr`` is not supplied, ``None`` is used (implying the function itself + if the view is a function, or the ``__call__`` callable attribute if the + view is a class). + +``renderer`` + Denotes the :term:`renderer` implementation which will be used to construct + a :term:`response` from the associated view callable's return value. (see + also :ref:`renderers_chapter`). + + This is either a single string term (e.g. ``json``) or a string implying a + path or :term:`asset specification` (e.g. ``templates/views.pt``) naming a + :term:`renderer` implementation. If the ``renderer`` value does not + contain a dot (``.``), the specified string will be used to look up a + renderer implementation, and that renderer implementation will be used to + construct a response from the view return value. If the ``renderer`` value + contains a dot (``.``), the specified term will be treated as a path, and + the filename extension of the last element in the path will be used to look + up the renderer implementation, which will be passed the full path. + + When the renderer is a path, although a path is usually just a simple + relative pathname (e.g. ``templates/foo.pt``, implying that a template + named "foo.pt" is in the "templates" directory relative to the directory of + the current :term:`package`), a path can be absolute, starting with a slash + on UNIX or a drive letter prefix on Windows. The path can alternately be a + :term:`asset specification` in the form + ``some.dotted.package_name:relative/path``, making it possible to address + template assets which live in a separate package. + + The ``renderer`` attribute is optional. If it is not defined, the "null" + renderer is assumed (no rendering is performed and the value is passed back + to the upstream :app:`Pyramid` machinery unmolested). Note that if the + view callable itself returns a :term:`response` (see :ref:`the_response`), + the specified renderer implementation is never called. + +``wrapper`` + The :term:`view name` of a different :term:`view configuration` which will + receive the response body of this view as the ``request.wrapped_body`` + attribute of its own :term:`request`, and the :term:`response` returned by + this view as the ``request.wrapped_response`` attribute of its own request. + Using a wrapper makes it possible to "chain" views together to form a + composite response. The response of the outermost wrapper view will be + returned to the user. The wrapper view will be found as any view is found: + see :ref:`view_lookup`. The "best" wrapper view will be found based on the + lookup ordering: "under the hood" this wrapper view is looked up via + ``pyramid.view.render_view_to_response(context, request, + 'wrapper_viewname')``. The context and request of a wrapper view is the + same context and request of the inner view. + + If ``wrapper`` is not supplied, no wrapper view is used. + +Predicate Arguments ++++++++++++++++++++ + +These arguments modify view lookup behavior. In general, the more predicate +arguments that are supplied, the more specific, and narrower the usage of the +configured view. + +``name`` + The :term:`view name` required to match this view callable. Read + :ref:`traversal_chapter` to understand the concept of a view name. + + If ``name`` is not supplied, the empty string is used (implying the default + view). + +``context`` + An object representing a Python class that the :term:`context` resource + must be an instance of *or* the :term:`interface` that the :term:`context` + resource must provide in order for this view to be found and called. This + predicate is true when the :term:`context` resource is an instance of the + represented class or if the :term:`context` resource provides the + represented interface; it is otherwise false. + + If ``context`` is not supplied, the value ``None``, which matches any + resource, is used. + +``route_name`` + If ``route_name`` is supplied, the view callable will be invoked only when + the named route has matched. + + This value must match the ``name`` of a :term:`route configuration` + declaration (see :ref:`urldispatch_chapter`) that must match before this + view will be called. Note that the ``route`` configuration referred to by + ``route_name`` will usually have a ``*traverse`` token in the value of its + ``pattern``, representing a part of the path that will be used by + :term:`traversal` against the result of the route's :term:`root factory`. + + If ``route_name`` is not supplied, the view callable will be have a chance + of being invoked if no other route was matched. This is when the + request/context pair found via :term:`resource location` does not indicate + it matched any configured route. + +``request_type`` + This value should be an :term:`interface` that the :term:`request` must + provide in order for this view to be found and called. + + If ``request_type`` is not supplied, the value ``None`` is used, implying + any request type. + + *This is an advanced feature, not often used by "civilians"*. + +``request_method`` + This value can either be one of the strings ``GET``, ``POST``, ``PUT``, + ``DELETE``, or ``HEAD`` representing an HTTP ``REQUEST_METHOD``. A view + declaration with this argument ensures that the view will only be called + when the request's ``method`` attribute (aka the ``REQUEST_METHOD`` of the + WSGI environment) string matches the supplied value. + + If ``request_method`` is not supplied, the view will be invoked regardless + of the ``REQUEST_METHOD`` of the :term:`WSGI` environment. + +``request_param`` + This value can be any string. A view declaration with this argument + ensures that the view will only be called when the :term:`request` has a + key in the ``request.params`` dictionary (an HTTP ``GET`` or ``POST`` + variable) that has a name which matches the supplied value. + + If the value supplied has a ``=`` sign in it, + e.g. ``request_params="foo=123"``, then the key (``foo``) must both exist + in the ``request.params`` dictionary, *and* the value must match the right + hand side of the expression (``123``) for the view to "match" the current + request. + + If ``request_param`` is not supplied, the view will be invoked without + consideration of keys and values in the ``request.params`` dictionary. + +``containment`` + This value should be a reference to a Python class or :term:`interface` + that a parent object in the context resource's :term:`lineage` must provide + in order for this view to be found and called. The resources in your + resource tree must be "location-aware" to use this feature. + + If ``containment`` is not supplied, the interfaces and classes in the + lineage are not considered when deciding whether or not to invoke the view + callable. + + See :ref:`location_aware` for more information about location-awareness. + +``xhr`` + This value should be either ``True`` or ``False``. If this value is + specified and is ``True``, the :term:`WSGI` environment must possess an + ``HTTP_X_REQUESTED_WITH`` (aka ``X-Requested-With``) header that has the + value ``XMLHttpRequest`` for the associated view callable to be found and + called. This is useful for detecting AJAX requests issued from jQuery, + Prototype and other Javascript libraries. + + If ``xhr`` is not specified, the ``HTTP_X_REQUESTED_WITH`` HTTP header is + not taken into consideration when deciding whether or not to invoke the + associated view callable. + +``accept`` + The value of this argument represents a match query for one or more + mimetypes in the ``Accept`` HTTP request header. If this value is + specified, it must be in one of the following forms: a mimetype match token + in the form ``text/plain``, a wildcard mimetype match token in the form + ``text/*`` or a match-all wildcard mimetype match token in the form + ``*/*``. If any of the forms matches the ``Accept`` header of the request, + this predicate will be true. + + If ``accept`` is not specified, the ``HTTP_ACCEPT`` HTTP header is not + taken into consideration when deciding whether or not to invoke the + associated view callable. + +``header`` + This value represents an HTTP header name or a header name/value pair. + + If ``header`` is specified, it must be a header name or a + ``headername:headervalue`` pair. + + If ``header`` is specified without a value (a bare header name only, + e.g. ``If-Modified-Since``), the view will only be invoked if the HTTP + header exists with any value in the request. + + If ``header`` is specified, and possesses a name/value pair + (e.g. ``User-Agent:Mozilla/.*``), the view will only be invoked if the HTTP + header exists *and* the HTTP header matches the value requested. When the + ``headervalue`` contains a ``:`` (colon), it will be considered a + name/value pair (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``). + The value portion should be a regular expression. + + Whether or not the value represents a header name or a header name/value + pair, the case of the header name is not significant. + + If ``header`` is not specified, the composition, presence or absence of + HTTP headers is not taken into consideration when deciding whether or not + to invoke the associated view callable. + +``path_info`` + This value represents a regular expression pattern that will be tested + against the ``PATH_INFO`` WSGI environment variable to decide whether or + not to call the associated view callable. If the regex matches, this + predicate will be ``True``. + + If ``path_info`` is not specified, the WSGI ``PATH_INFO`` is not taken into + consideration when deciding whether or not to invoke the associated view + callable. + +``custom_predicates`` + If ``custom_predicates`` is specified, it must be a sequence of references + to custom predicate callables. Use custom predicates when no set of + predefined predicates do what you need. Custom predicates can be combined + with predefined predicates as necessary. Each custom predicate callable + should accept two arguments: ``context`` and ``request`` and should return + either ``True`` or ``False`` after doing arbitrary evaluation of the + context resource and/or the request. If all callables return ``True``, the + associated view callable will be considered viable for a given request. + + If ``custom_predicates`` is not specified, no custom predicates are + used. + +.. index:: + single: view_config decorator + +.. _mapping_views_using_a_decorator_section: + +View Configuration Using the ``@view_config`` Decorator +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For better locality of reference, you may use the +:class:`pyramid.view.view_config` decorator to associate your view functions +with URLs instead of using :term:`ZCML` or imperative configuration for the +same purpose. + +.. warning:: + + Using this feature tends to slows down application startup slightly, as + more work is performed at application startup to scan for view + declarations. + +Usage of the ``view_config`` decorator is a form of :term:`declarative +configuration`, like ZCML, but in decorator form. +:class:`pyramid.view.view_config` can be used to associate :term:`view +configuration` information -- as done via the equivalent imperative code or +ZCML -- with a function that acts as a :app:`Pyramid` view callable. All +arguments to the :meth:`pyramid.config.Configurator.add_view` method (save +for the ``view`` argument) are available in decorator form and mean precisely +the same thing. + +An example of the :class:`pyramid.view.view_config` decorator might reside in +a :app:`Pyramid` application module ``views.py``: + +.. ignore-next-block +.. code-block:: python + :linenos: + + from resources import MyResource + from pyramid.view import view_config + from pyramid.response import Response + + @view_config(name='my_view', request_method='POST', context=MyResource, + permission='read') + def my_view(request): + return Response('OK') + +Using this decorator as above replaces the need to add this imperative +configuration stanza: + +.. ignore-next-block +.. code-block:: python + :linenos: + + config.add_view('.views.my_view', name='my_view', request_method='POST', + context=MyResource, permission='read') + +All arguments to ``view_config`` may be omitted. For example: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + from pyramid.view import view_config + + @view_config() + def my_view(request): + """ My view """ + return Response() + +Such a registration as the one directly above implies that the view name will +be ``my_view``, registered with a ``context`` argument that matches any +resource type, using no permission, registered against requests with any +request method, request type, request param, route name, or containment. + +The mere existence of a ``@view_config`` decorator doesn't suffice to perform +view configuration. All that the decorator does is "annotate" the function +with your configuration declarations, it doesn't process them. To make +:app:`Pyramid` process your :class:`pyramid.view.view_config` declarations, +you *must* do use the ``scan`` method of a +:class:`pyramid.config.Configurator`: + +.. code-block:: python + :linenos: + + # config is assumed to be an instance of the + # pyramid.config.Configurator class + config.scan() + +.. note:: See :ref:`zcml_scanning` for information about how to invoke a scan + via ZCML (if you're not using imperative configuration). + +Please see :ref:`decorations_and_code_scanning` for detailed information +about what happens when code is scanned for configuration declarations +resulting from use of decorators like :class:`pyramid.view.view_config`. + +See :ref:`configuration_module` for additional API arguments to the +:meth:`pyramid.config.Configurator.scan` method. For example, the method +allows you to supply a ``package`` argument to better control exactly *which* +code will be scanned. + +``@view_config`` Placement +++++++++++++++++++++++++++ + +A :class:`pyramid.view.view_config` decorator can be placed in various points +in your application. + +If your view callable is a function, it may be used as a function decorator: + +.. code-block:: python + :linenos: + + from pyramid.view import view_config + from pyramid.response import Response + + @view_config(name='edit') + def edit(request): + return Response('edited!') + +If your view callable is a class, the decorator can also be used as a class +decorator in Python 2.6 and better (Python 2.5 and below do not support class +decorators). All the arguments to the decorator are the same when applied +against a class as when they are applied against a function. For example: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + from pyramid.view import view_config + + @view_config() + class MyView(object): + def __init__(self, request): + self.request = request + + def __call__(self): + return Response('hello') + +You can use the :class:`pyramid.view.view_config` decorator as a simple +callable to manually decorate classes in Python 2.5 and below without the +decorator syntactic sugar, if you wish: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + from pyramid.view import view_config + + class MyView(object): + def __init__(self, request): + self.request = request + + def __call__(self): + return Response('hello') + + my_view = view_config()(MyView) + +More than one :class:`pyramid.view.view_config` decorator can be stacked on +top of any number of others. Each decorator creates a separate view +registration. For example: + +.. code-block:: python + :linenos: + + from pyramid.view import view_config + from pyramid.response import Response + + @view_config(name='edit') + @view_config(name='change') + def edit(request): + return Response('edited!') + +This registers the same view under two different names. + +The decorator can also be used against class methods: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + from pyramid.view import view_config + + class MyView(object): + def __init__(self, request): + self.request = request + + @view_config(name='hello') + def amethod(self): + return Response('hello') + +When the decorator is used against a class method, a view is registered for +the *class*, so the class constructor must accept an argument list in one of +two forms: either it must accept a single argument ``request`` or it must +accept two arguments, ``context, request``. + +The method which is decorated must return a :term:`response`. + +Using the decorator against a particular method of a class is equivalent to +using the ``attr`` parameter in a decorator attached to the class itself. +For example, the above registration implied by the decorator being used +against the ``amethod`` method could be spelled equivalently as the below: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + from pyramid.view import view_config + + @view_config(attr='amethod', name='hello') + class MyView(object): + def __init__(self, request): + self.request = request + + def amethod(self): + return Response('hello') + +.. index:: + single: add_view + +.. _mapping_views_using_imperative_config_section: + +View Registration Using :meth:`~pyramid.config.Configurator.add_view` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The :meth:`pyramid.config.Configurator.add_view` method within +:ref:`configuration_module` is used to configure a view imperatively. The +arguments to this method are very similar to the arguments that you provide +to the ``@view_config`` decorator. For example: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + + def hello_world(request): + return Response('hello!') + + # config is assumed to be an instance of the + # pyramid.config.Configurator class + config.add_view(hello_world, name='hello.html') + +The first argument, ``view``, is required. It must either be a Python object +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: + +Handler Registration Using :meth:`~pyramid.config.Configurator.add_handler` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:app:`Pyramid` provides the special concept of a :term:`view handler`. View +handlers are view classes that implement a number of methods, each of which +is a :term:`view callable` as a convenience for :term:`URL dispatch` users. + +.. note:: + + View handlers are *not* useful when using :term:`traversal`, only when using + :term:`url dispatch`. + +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. The method name is the +default *action name* of a handler view callable. + +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 "plain" view class. Its ``__init__`` is called with a request object (see +:ref:`class_as_view`). It implements methods, each of which is a :term:`view +callable`. When a request enters the system which corresponds with an +*action* related to one of its view callable methods, this method is called, +and it is expected to return a response. + +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 {} + +The :class:`pyramid.view.action` decorator is used to fine-tune the view +parameters for each potential view callable which is a method of the handler. + +Handlers are added to application configuration via the +:meth:`pyramid.config.Configurator.add_handler` API. 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}``, and each method of the ``Hello`` class will then be +examined to see if it should be registered as a potential view callable when +the ``/hello/{action}`` pattern matches. 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. By default, the action name for a method of a +handler is the method name. + +If the URL was ``/hello/index``, the above example pattern would match, and, +by default, the ``index`` method of the ``Hello`` class would be called. + +Alternatively, the action can be declared specifically for a URL to be +registered for 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 ++++++++++++++++++++++++++++++++ + +A handler class 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 + +.. _using_resource_interfaces: + +Using Resource Interfaces In View Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Instead of registering your views with a ``context`` that names a Python +resource *class*, you can optionally register a view callable with a +``context`` which is an :term:`interface`. An interface can be attached +arbitrarily to any resource object. View lookup treats context interfaces +specially, and therefore the identity of a resource can be divorced from that +of the class which implements it. As a result, associating a view with an +interface can provide more flexibility for sharing a single view between two +or more different implementations of a resource type. For example, if two +resource objects of different Python class types share the same interface, +you can use the same view configuration to specify both of them as a +``context``. + +In order to make use of interfaces in your application during view dispatch, +you must create an interface and mark up your resource classes or instances +with interface declarations that refer to this interface. + +To attach an interface to a resource *class*, you define the interface and +use the :func:`zope.interface.implements` function to associate the interface +with the class. + +.. code-block:: python + :linenos: + + from zope.interface import Interface + from zope.interface import implements + + class IHello(Interface): + """ A marker interface """ + + class Hello(object): + implements(IHello) + +To attach an interface to a resource *instance*, you define the interface and +use the :func:`zope.interface.alsoProvides` function to associate the +interface with the instance. This function mutates the instance in such a +way that the interface is attached to it. + +.. code-block:: python + :linenos: + + from zope.interface import Interface + from zope.interface import alsoProvides + + class IHello(Interface): + """ A marker interface """ + + class Hello(object): + pass + + def make_hello(): + hello = Hello() + alsoProvides(hello, IHello) + return hello + +Regardless of how you associate an interface, with a resource instance, or a +resource class, the resulting code to associate that interface with a view +callable is the same. Assuming the above code that defines an ``IHello`` +interface lives in the root of your application, and its module is named +"resources.py", the interface declaration below will associate the +``mypackage.views.hello_world`` view with resources that implement, or +provide, this interface. + +.. code-block:: python + :linenos: + + # config is an instance of pyramid.config.Configurator + + config.add_view('mypackage.views.hello_world', name='hello.html', + context='mypackage.resources.IHello') + +Any time a resource that is determined to be the :term:`context` provides +this interface, and a view named ``hello.html`` is looked up against it as +per the URL, the ``mypackage.views.hello_world`` view callable will be +invoked. + +Note, in cases where a view is registered against a resource class, and a +view is also registered against an interface that the resource class +implements, an ambiguity arises. Views registered for the resource class take +precedence over any views registered for any interface the resource class +implements. Thus, if one view configuration names a ``context`` of both the +class type of a resource, and another view configuration names a ``context`` +of interface implemented by the resource's class, and both view +configurations are otherwise identical, the view registered for the context's +class will "win". + +For more information about defining resources with interfaces for use within +view configuration, see :ref:`resources_which_implement_interfaces`. + +.. index:: + single: view security + pair: security; view + +.. _view_security_section: + +Configuring View Security +~~~~~~~~~~~~~~~~~~~~~~~~~ + +If an :term:`authorization policy` is active, any :term:`permission` attached +to a :term:`view configuration` found during view lookup will be verified. +This will ensure that the currently authenticated user possesses that +permission against the :term:`context` resource before the view function is +actually called. Here's an example of specifying a permission in a view +configuration using :meth:`pyramid.config.Configurator.add_view`: + +.. code-block:: python + :linenos: + + # config is an instance of pyramid.config.Configurator + + config.add_view('myproject.views.add_entry', name='add.html', + context='myproject.resources.IBlog', permission='add') + +When an :term:`authorization policy` is enabled, this view will be protected +with the ``add`` permission. The view will *not be called* if the user does +not possess the ``add`` permission relative to the current :term:`context`. +Instead the :term:`forbidden view` result will be returned to the client as +per :ref:`protecting_views`. + +.. index:: + single: debugging not found errors + single: not found error (debugging) + +.. _debug_notfound_section: + +:exc:`NotFound` Errors +~~~~~~~~~~~~~~~~~~~~~~ + +It's useful to be able to debug :exc:`NotFound` error responses when they +occur unexpectedly due to an application registry misconfiguration. To debug +these errors, use the ``PYRAMID_DEBUG_NOTFOUND`` environment variable or the +``debug_notfound`` configuration file setting. Details of why a view was not +found will be printed to ``stderr``, and the browser representation of the +error will include the same information. See :ref:`environment_chapter` for +more information about how, and where to set these values. + -- cgit v1.2.3 From db14e3eea2a56f67a2db34369283e7a15813d971 Mon Sep 17 00:00:00 2001 From: Casey Duncan Date: Sun, 2 Jan 2011 23:52:55 -0700 Subject: :term: not :mod: --- docs/narr/viewconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/viewconfig.rst') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 39c0a0d1f..299342b74 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -76,7 +76,7 @@ All forms of view configuration accept the same general types of arguments. Many arguments supplied during view configuration are :term:`view predicate` arguments. View predicate arguments used during view configuration are used -to narrow the set of circumstances in which :mod:`view lookup` will find a +to narrow the set of circumstances in which :term:`view lookup` will find a particular view callable. In general, the fewer number of predicates which are supplied to a -- cgit v1.2.3 From 245316b0159f75269a1a7a4c5327c712e1475cc2 Mon Sep 17 00:00:00 2001 From: Casey Duncan Date: Sun, 2 Jan 2011 23:57:43 -0700 Subject: add intro paragraph to view config chapt --- docs/narr/viewconfig.rst | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'docs/narr/viewconfig.rst') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 299342b74..372e520b4 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -8,6 +8,11 @@ View Configuration .. index:: single: view lookup +:term:`View configuration` controls how :term:`view lookup` operates in +your application. In earlier chapters, you have been exposed to a few +simple view configuration declarations without much explanation. In this +chapter we will explore the subject in detail. + .. _view_lookup: View Lookup and Invocation -- cgit v1.2.3 From f4fcd32e10f0d863ebc61fc09c81e02d103ffe2e Mon Sep 17 00:00:00 2001 From: Rob Miller Date: Thu, 13 Jan 2011 00:52:40 -0800 Subject: First pass at documenting the __action_decorator__ feature of a view handler. --- docs/narr/viewconfig.rst | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'docs/narr/viewconfig.rst') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index f8b3fdb24..c11fc1697 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -841,6 +841,35 @@ 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. +Handler ``__action_decorator__`` Attribute +++++++++++++++++++++++++++++++++++++++++++ + +If a handler class has an ``__action_decorator__`` attribute, then the +value of the class attribute will be passed in as the ``decorator`` +argument every time a handler action is registered as a view callable. +This means that, like anything passed to ``add_view()`` as the +``decorator`` argument, ``__action_decorator__`` must be a callable +accepting a single argument. This argument will itself be a callable +accepting ``(context, request)`` arguments, and +``__action_decorator__`` must return a replacement callable with the +same call signature. + +Note that, since handler actions are registered as views against the +handler class and not a handler instance, any ``__action_decorator__`` +attribute must *not* be a regular instance method. Defining an +``__action_decorator__`` instance method on a handler class will +result in a :exc:`ConfigurationError`. Instead, ``__action_decorator__`` +can be any other type of callable: a staticmethod, classmethod, function, +or some sort of callable instance. + +.. note:: + + In a Pylons 1.0 controller, it was possible to override the ``__call__()`` + method, which allowed a developer to "wrap" the entire action invocation, + with a try/except or any other arbitrary code. In :app:`Pyramid`, this + can be emulated with the use of an ``__action_decorator__`` classmethod + on your handler class. + .. index:: single: resource interfaces -- cgit v1.2.3 From 2fa5764cb1fd001550ae7c985333718667b86b1c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 16 Jan 2011 17:41:10 -0500 Subject: - The ``pylons_minimal``, ``pylons_basic`` and ``pylons_sqla`` paster templates were removed. Use ``pyramid_sqla`` (available from PyPI) as a generic replacement for Pylons-esque development. - All references to ``add_handler`` and the ``handler`` ZCML directive have been removed from the docs, and stubs which point to ``pylons_handlers`` package have replaced them. --- docs/narr/viewconfig.rst | 286 ++--------------------------------------------- 1 file changed, 8 insertions(+), 278 deletions(-) (limited to 'docs/narr/viewconfig.rst') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index c11fc1697..9b2074a70 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -63,14 +63,15 @@ View configuration is performed in one of these ways: :meth:`pyramid.config.Configurator.add_route` method, passing a ``view`` argument specifying a view callable. -- by using the :meth:`pyramid.config.Configurator.add_handler` against a - :term:`view handler` class (useful only for :term:`URL dispatch` - applications). +.. note:: You can also add view configuration by adding a ```` or + ```` declaration to :term:`ZCML` used by your application as per + :ref:`mapping_views_using_zcml_section`, :ref:`view_directive` or + :ref:`route_directive`. -.. note:: You can also add view configuration by adding a ````, - ```` or ```` declaration to :term:`ZCML` used by your - application as per :ref:`mapping_views_using_zcml_section`, - :ref:`view_directive`, :ref:`route_directive` or :ref:`handler_directive`. +.. note:: A package named ``pyramid_handlers`` (available from PyPI) provides + an analogue of :term:`Pylons` -style "controllers", which are a special + kind of view class which provides more automation when your application + uses :term:`URL dispatch` solely. .. _view_configuration_parameters: @@ -599,277 +600,6 @@ 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: - -Handler Registration Using :meth:`~pyramid.config.Configurator.add_handler` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:app:`Pyramid` provides the special concept of a :term:`view handler`. View -handlers are view classes that implement a number of methods, each of which -is a :term:`view callable` as a convenience for :term:`URL dispatch` users. - -.. note:: - - View handlers are *not* useful when using :term:`traversal`, only when using - :term:`url dispatch`. - -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. The method name is the -default *action name* of a handler view callable. - -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 "plain" view class. Its ``__init__`` is called with a request object (see -:ref:`class_as_view`). It implements methods, each of which is a :term:`view -callable`. When a request enters the system which corresponds with an -*action* related to one of its view callable methods, this method is called, -and it is expected to return a response. - -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 {} - -The :class:`pyramid.view.action` decorator is used to fine-tune the view -parameters for each potential view callable which is a method of the handler. - -Handlers are added to application configuration via the -:meth:`pyramid.config.Configurator.add_handler` API. 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}``, and each method of the ``Hello`` class will then be -examined to see if it should be registered as a potential view callable when -the ``/hello/{action}`` pattern matches. 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. By default, the action name for a method of a -handler is the method name. - -If the URL was ``/hello/index``, the above example pattern would match, and, -by default, the ``index`` method of the ``Hello`` class would be called. - -Alternatively, the action can be declared specifically for a URL to be -registered for 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 -+++++++++++++++++++++++++++++++ - -A handler class 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. - -Handler ``__action_decorator__`` Attribute -++++++++++++++++++++++++++++++++++++++++++ - -If a handler class has an ``__action_decorator__`` attribute, then the -value of the class attribute will be passed in as the ``decorator`` -argument every time a handler action is registered as a view callable. -This means that, like anything passed to ``add_view()`` as the -``decorator`` argument, ``__action_decorator__`` must be a callable -accepting a single argument. This argument will itself be a callable -accepting ``(context, request)`` arguments, and -``__action_decorator__`` must return a replacement callable with the -same call signature. - -Note that, since handler actions are registered as views against the -handler class and not a handler instance, any ``__action_decorator__`` -attribute must *not* be a regular instance method. Defining an -``__action_decorator__`` instance method on a handler class will -result in a :exc:`ConfigurationError`. Instead, ``__action_decorator__`` -can be any other type of callable: a staticmethod, classmethod, function, -or some sort of callable instance. - -.. note:: - - In a Pylons 1.0 controller, it was possible to override the ``__call__()`` - method, which allowed a developer to "wrap" the entire action invocation, - with a try/except or any other arbitrary code. In :app:`Pyramid`, this - can be emulated with the use of an ``__action_decorator__`` classmethod - on your handler class. - .. index:: single: resource interfaces -- cgit v1.2.3 From c9c3c487bcaedeca97bb6463a00188b0dc01203a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 18 Jan 2011 12:25:56 -0500 Subject: - Most references to ZCML in narrative chapters have been removed or redirected to ``pyramid_zcml`` locations. --- docs/narr/viewconfig.rst | 8 -------- 1 file changed, 8 deletions(-) (limited to 'docs/narr/viewconfig.rst') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 9b2074a70..3f2b1b179 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -63,11 +63,6 @@ View configuration is performed in one of these ways: :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 ```` or - ```` declaration to :term:`ZCML` used by your application as per - :ref:`mapping_views_using_zcml_section`, :ref:`view_directive` or - :ref:`route_directive`. - .. note:: A package named ``pyramid_handlers`` (available from PyPI) provides an analogue of :term:`Pylons` -style "controllers", which are a special kind of view class which provides more automation when your application @@ -443,9 +438,6 @@ you *must* do use the ``scan`` method of a # pyramid.config.Configurator class config.scan() -.. note:: See :ref:`zcml_scanning` for information about how to invoke a scan - via ZCML (if you're not using imperative configuration). - Please see :ref:`decorations_and_code_scanning` for detailed information about what happens when code is scanned for configuration declarations resulting from use of decorators like :class:`pyramid.view.view_config`. -- cgit v1.2.3 From 7a2ab7108c567bdc792c4e8f999e6ef0dbf24917 Mon Sep 17 00:00:00 2001 From: Chris Beelby Date: Thu, 27 Jan 2011 13:06:57 -0500 Subject: First batch of fixes for typo's and other language issues. --- docs/narr/viewconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/viewconfig.rst') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 3f2b1b179..092bd6012 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -157,7 +157,7 @@ Non-Predicate Arguments The ``renderer`` attribute is optional. If it is not defined, the "null" renderer is assumed (no rendering is performed and the value is passed back - to the upstream :app:`Pyramid` machinery unmolested). Note that if the + to the upstream :app:`Pyramid` machinery unchanged). Note that if the view callable itself returns a :term:`response` (see :ref:`the_response`), the specified renderer implementation is never called. -- cgit v1.2.3 From 70acd25f40f32fc6cbb3b5d38a695b8982b52a31 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 27 Jan 2011 23:06:55 -0500 Subject: module name contractions --- docs/narr/viewconfig.rst | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'docs/narr/viewconfig.rst') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 3f2b1b179..63a1b11d6 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -51,11 +51,9 @@ View configuration is performed in one of these ways: - by running a :term:`scan` against application source code which has a :class:`pyramid.view.view_config` decorator attached to a Python object as - per :class:`pyramid.view.view_config` and - :ref:`mapping_views_using_a_decorator_section`. + per :ref:`mapping_views_using_a_decorator_section`. - by using the :meth:`pyramid.config.Configurator.add_view` method as per - :meth:`pyramid.config.Configurator.add_view` and :ref:`mapping_views_using_imperative_config_section`. - By specifying a view within a :term:`route configuration`. View @@ -373,14 +371,14 @@ same purpose. Usage of the ``view_config`` decorator is a form of :term:`declarative configuration`, like ZCML, but in decorator form. -:class:`pyramid.view.view_config` can be used to associate :term:`view +:class:`~pyramid.view.view_config` can be used to associate :term:`view configuration` information -- as done via the equivalent imperative code or ZCML -- with a function that acts as a :app:`Pyramid` view callable. All arguments to the :meth:`pyramid.config.Configurator.add_view` method (save for the ``view`` argument) are available in decorator form and mean precisely the same thing. -An example of the :class:`pyramid.view.view_config` decorator might reside in +An example of the :class:`~pyramid.view.view_config` decorator might reside in a :app:`Pyramid` application module ``views.py``: .. ignore-next-block @@ -427,9 +425,9 @@ request method, request type, request param, route name, or containment. The mere existence of a ``@view_config`` decorator doesn't suffice to perform view configuration. All that the decorator does is "annotate" the function with your configuration declarations, it doesn't process them. To make -:app:`Pyramid` process your :class:`pyramid.view.view_config` declarations, +:app:`Pyramid` process your :class:`~pyramid.view.view_config` declarations, you *must* do use the ``scan`` method of a -:class:`pyramid.config.Configurator`: +:class:`~pyramid.config.Configurator`: .. code-block:: python :linenos: @@ -440,17 +438,17 @@ you *must* do use the ``scan`` method of a Please see :ref:`decorations_and_code_scanning` for detailed information about what happens when code is scanned for configuration declarations -resulting from use of decorators like :class:`pyramid.view.view_config`. +resulting from use of decorators like :class:`~pyramid.view.view_config`. See :ref:`configuration_module` for additional API arguments to the -:meth:`pyramid.config.Configurator.scan` method. For example, the method +:meth:`~pyramid.config.Configurator.scan` method. For example, the method allows you to supply a ``package`` argument to better control exactly *which* code will be scanned. ``@view_config`` Placement ++++++++++++++++++++++++++ -A :class:`pyramid.view.view_config` decorator can be placed in various points +A :class:`~pyramid.view.view_config` decorator can be placed in various points in your application. If your view callable is a function, it may be used as a function decorator: @@ -484,7 +482,7 @@ against a class as when they are applied against a function. For example: def __call__(self): return Response('hello') -You can use the :class:`pyramid.view.view_config` decorator as a simple +You can use the :class:`~pyramid.view.view_config` decorator as a simple callable to manually decorate classes in Python 2.5 and below without the decorator syntactic sugar, if you wish: @@ -503,7 +501,7 @@ decorator syntactic sugar, if you wish: my_view = view_config()(MyView) -More than one :class:`pyramid.view.view_config` decorator can be stacked on +More than one :class:`~pyramid.view.view_config` decorator can be stacked on top of any number of others. Each decorator creates a separate view registration. For example: @@ -702,7 +700,7 @@ to a :term:`view configuration` found during view lookup will be verified. This will ensure that the currently authenticated user possesses that permission against the :term:`context` resource before the view function is actually called. Here's an example of specifying a permission in a view -configuration using :meth:`pyramid.config.Configurator.add_view`: +configuration using :meth:`~pyramid.config.Configurator.add_view`: .. code-block:: python :linenos: -- cgit v1.2.3 From 8d7dbf0debab8e408e659411618df0faaed13afd Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 30 Jan 2011 16:56:01 -0500 Subject: inappropriate mentions of alternate declarative forms --- docs/narr/viewconfig.rst | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'docs/narr/viewconfig.rst') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 63a1b11d6..1e32e200e 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -360,8 +360,7 @@ View Configuration Using the ``@view_config`` Decorator For better locality of reference, you may use the :class:`pyramid.view.view_config` decorator to associate your view functions -with URLs instead of using :term:`ZCML` or imperative configuration for the -same purpose. +with URLs instead of using imperative configuration for the same purpose. .. warning:: @@ -370,13 +369,12 @@ same purpose. declarations. Usage of the ``view_config`` decorator is a form of :term:`declarative -configuration`, like ZCML, but in decorator form. -:class:`~pyramid.view.view_config` can be used to associate :term:`view -configuration` information -- as done via the equivalent imperative code or -ZCML -- with a function that acts as a :app:`Pyramid` view callable. All -arguments to the :meth:`pyramid.config.Configurator.add_view` method (save -for the ``view`` argument) are available in decorator form and mean precisely -the same thing. +configuration` in decorator form. :class:`~pyramid.view.view_config` can be +used to associate :term:`view configuration` information -- as done via the +equivalent imperative code -- with a function that acts as a :app:`Pyramid` +view callable. All arguments to the +:meth:`pyramid.config.Configurator.add_view` method (save for the ``view`` +argument) are available in decorator form and mean precisely the same thing. An example of the :class:`~pyramid.view.view_config` decorator might reside in a :app:`Pyramid` application module ``views.py``: -- cgit v1.2.3 From 86fc0cb9039d219e4a063826ac0931d47fe65de0 Mon Sep 17 00:00:00 2001 From: Chris Beelby Date: Sun, 30 Jan 2011 17:38:11 -0500 Subject: More errors in narrative fixed. --- docs/narr/viewconfig.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr/viewconfig.rst') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 092bd6012..c45f053cf 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -178,7 +178,7 @@ Non-Predicate Arguments If ``wrapper`` is not supplied, no wrapper view is used. ``decorator`` - A :term:`dotted Python name` to function (or the function itself) which + A :term:`dotted Python name` to a function (or the function itself) which will be used to decorate the registered :term:`view callable`. The decorator function will be called with the view callable as a single argument. The view callable it is passed will accept ``(context, @@ -244,7 +244,7 @@ configured view. *This is an advanced feature, not often used by "civilians"*. ``request_method`` - This value can either be one of the strings ``GET``, ``POST``, ``PUT``, + This value can be one of the strings ``GET``, ``POST``, ``PUT``, ``DELETE``, or ``HEAD`` representing an HTTP ``REQUEST_METHOD``. A view declaration with this argument ensures that the view will only be called when the request's ``method`` attribute (aka the ``REQUEST_METHOD`` of the @@ -403,7 +403,7 @@ configuration stanza: .. code-block:: python :linenos: - config.add_view('.views.my_view', name='my_view', request_method='POST', + config.add_view('mypackage.views.my_view', name='my_view', request_method='POST', context=MyResource, permission='read') All arguments to ``view_config`` may be omitted. For example: @@ -428,7 +428,7 @@ The mere existence of a ``@view_config`` decorator doesn't suffice to perform view configuration. All that the decorator does is "annotate" the function with your configuration declarations, it doesn't process them. To make :app:`Pyramid` process your :class:`pyramid.view.view_config` declarations, -you *must* do use the ``scan`` method of a +you *must* use the ``scan`` method of a :class:`pyramid.config.Configurator`: .. code-block:: python -- cgit v1.2.3 From fe164c184edaf810b3c1b4afb757672e2befa2ec Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 26 Feb 2011 11:57:26 -0500 Subject: it's request_param --- docs/narr/viewconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/viewconfig.rst') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 0a6d9ee61..9b2500a2b 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -258,7 +258,7 @@ configured view. variable) that has a name which matches the supplied value. If the value supplied has a ``=`` sign in it, - e.g. ``request_params="foo=123"``, then the key (``foo``) must both exist + e.g. ``request_param="foo=123"``, then the key (``foo``) must both exist in the ``request.params`` dictionary, *and* the value must match the right hand side of the expression (``123``) for the view to "match" the current request. -- cgit v1.2.3