Chris McDonough
2011-07-20 8cb68208d42899b50025418812bb339f578d553f
- Reordered chapters in narrative section for better new user friendliness.

- Added more indexing markers to sections in documentation.
9 files modified
459 ■■■■ changed files
CHANGES.txt 4 ●●●● patch | view | raw | blame | history
docs/index.rst 14 ●●●● patch | view | raw | blame | history
docs/latexindex.rst 15 ●●●● patch | view | raw | blame | history
docs/narr/firstapp.rst 3 ●●●●● patch | view | raw | blame | history
docs/narr/renderers.rst 8 ●●●● patch | view | raw | blame | history
docs/narr/traversal.rst 97 ●●●●● patch | view | raw | blame | history
docs/narr/urldispatch.rst 117 ●●●●● patch | view | raw | blame | history
docs/narr/viewconfig.rst 133 ●●●● patch | view | raw | blame | history
docs/narr/views.rst 68 ●●●●● patch | view | raw | blame | history
CHANGES.txt
@@ -6,6 +6,10 @@
- Fixed two typos in wiki2 (SQLA + URL Dispatch) tutorial.
- Reordered chapters in narrative section for better new user friendliness.
- Added more indexing markers to sections in documentation.
1.1b4 (2011-07-18)
==================
docs/index.rst
@@ -43,24 +43,24 @@
   narr/project
   narr/startup
   narr/urldispatch
   narr/muchadoabouttraversal
   narr/traversal
   narr/views
   narr/renderers
   narr/templates
   narr/viewconfig
   narr/resources
   narr/assets
   narr/webob
   narr/sessions
   narr/security
   narr/hybrid
   narr/i18n
   narr/vhosting
   narr/events
   narr/environment
   narr/commandline
   narr/i18n
   narr/vhosting
   narr/testing
   narr/resources
   narr/muchadoabouttraversal
   narr/traversal
   narr/security
   narr/hybrid
   narr/hooks
   narr/advconfig
   narr/extending
docs/latexindex.rst
@@ -32,23 +32,24 @@
   narr/firstapp
   narr/project
   narr/urldispatch
   narr/muchadoabouttraversal
   narr/traversal
   narr/views
   narr/renderers
   narr/templates
   narr/viewconfig
   narr/resources
   narr/assets
   narr/webob
   narr/sessions
   narr/security
   narr/hybrid
   narr/i18n
   narr/vhosting
   narr/events
   narr/environment
   narr/commandline
   narr/i18n
   narr/vhosting
   narr/testing
   narr/resources
   narr/muchadoabouttraversal
   narr/traversal
   narr/security
   narr/hybrid
   narr/hooks
   narr/advconfig
   narr/extending
docs/narr/firstapp.rst
@@ -322,6 +322,3 @@
For more information about :term:`view configuration`, see
:ref:`view_config_chapter`.
An example of using *declarative* configuration (:term:`ZCML`) instead of
imperative configuration to create a similar "hello world" is available
within the documentation for :term:`pyramid_zcml`.
docs/narr/renderers.rst
@@ -3,10 +3,10 @@
Renderers
=========
A view needn't *always* return a :term:`Response` object.  If a view
happens to return something which does not implement the Pyramid
Response interface, :app:`Pyramid` will attempt to use a
:term:`renderer` to construct a response.  For example:
A view callable needn't *always* return a :term:`Response` object.  If a view
happens to return something which does not implement the Pyramid Response
interface, :app:`Pyramid` will attempt to use a :term:`renderer` to construct
a response.  For example:
.. code-block:: python
   :linenos:
docs/narr/traversal.rst
@@ -456,6 +456,103 @@
   -specific request attributes are also available as described in
   :ref:`special_request_attributes`.
.. 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`.
References
----------
docs/narr/urldispatch.rst
@@ -6,28 +6,12 @@
URL Dispatch
============
:term:`URL dispatch` provides a simple way to map URLs to :term:`view`
code using a simple pattern matching language.  An ordered set of
patterns is checked one-by-one.  If one of the patterns matches the path
information associated with a request, a particular :term:`view
callable` is invoked.
:term:`URL dispatch` is one of two ways to perform :term:`resource location`
in :app:`Pyramid`; the other way is to use :term:`traversal`.  If no route is
matched using :term:`URL dispatch`, :app:`Pyramid` falls back to
:term:`traversal` to handle the :term:`request`.
It is the responsibility of the :term:`resource location` subsystem
(i.e., :term:`URL dispatch` or :term:`traversal`) to find the resource
object that is the :term:`context` of the :term:`request`. Once the
:term:`context` is determined, :term:`view lookup` is then responsible
for finding and invoking a :term:`view callable`.  A view callable is a
specific bit of code, defined in your application, that receives the
:term:`request` and returns a :term:`response` object.
Where appropriate, we will describe how view lookup interacts with
:term:`resource location`.  The :ref:`view_config_chapter` chapter describes
the details of :term:`view lookup`.
:term:`URL dispatch` provides a simple way to map URLs to :term:`view` code
using a simple pattern matching language.  An ordered set of patterns is
checked one-by-one.  If one of the patterns matches the path information
associated with a request, a particular :term:`view callable` is invoked.  A
view callable is a specific bit of code, defined in your application, that
receives the :term:`request` and returns a :term:`response` object.
High-Level Operational Overview
-------------------------------
@@ -37,18 +21,11 @@
matching patterns present in a *route map*.
If any route pattern matches the information in the :term:`request`,
:app:`Pyramid` will invoke :term:`view lookup` using a :term:`context`
resource generated by the route match.
:app:`Pyramid` will invoke :term:`view lookup` to find a matching view.
However, if no route pattern matches the information in the :term:`request`
provided to :app:`Pyramid`, it will fail over to using :term:`traversal` to
perform resource location and view lookup.
Technically, URL dispatch is a :term:`resource location` mechanism (it finds
a context object).  But ironically, using URL dispatch (instead of
:term:`traversal`) allows you to avoid thinking about your application in
terms of "resources" entirely, because it allows you to directly map a
:term:`view callable` to a route.
If no route pattern in the route map matches the information in the
:term:`request` provided in your application, :app:`Pyramid` will fail over
to using :term:`traversal` to perform resource location and view lookup.
.. index::
   single: route configuration
@@ -89,8 +66,8 @@
When a :term:`view callable` added to the configuration by way of
:meth:`~pyramid.config.Configurator.add_view` bcomes associated with a route
via its ``route_name`` predicate, that view callable will always be found
and invoked when the associated route pattern matches during a request.
via its ``route_name`` predicate, that view callable will always be found and
invoked when the associated route pattern matches during a request.
More commonly, you will not use any ``add_view`` statements in your project's
"setup" code, instead only using ``add_route`` statements using a
@@ -323,12 +300,11 @@
Route configuration declarations are evaluated in a specific order when a
request enters the system. As a result, the order of route configuration
declarations is very important.
The order that routes declarations are evaluated is the order in which they
are added to the application at startup time.  This is unlike
:term:`traversal`, which depends on emergent behavior which happens as a
result of traversing a resource tree.
declarations is very important.  The order that routes declarations are
evaluated is the order in which they are added to the application at startup
time.  (This is unlike a different way of mapping URLs to code that
:app:`Pyramid` provides, named :term:`traversal`, which does not depend on
pattern ordering).
For routes added via the :mod:`~pyramid.config.Configurator.add_route` method,
the order that routes are evaluated is the order in which they are added to
@@ -551,27 +527,30 @@
The main purpose of route configuration is to match (or not match) the
``PATH_INFO`` present in the WSGI environment provided during a request
against a URL path pattern.
against a URL path pattern.  ``PATH_INFO`` represents the path portion of the
URL that was requested.
The way that :app:`Pyramid` does this is very simple.  When a request enters
the system, for each route configuration declaration present in the system,
:app:`Pyramid` checks the ``PATH_INFO`` against the pattern declared.
If any route matches, the route matching process stops.  The :term:`request`
is decorated with a special :term:`interface` which describes it as a "route
request", the :term:`context` resource is generated, and the context and the
resulting request are handed off to :term:`view lookup`.  During view lookup,
if a :term:`view callable` associated with the matched route is found, that
view is called.
:app:`Pyramid` checks the request's ``PATH_INFO`` against the pattern
declared.  This checking happens in the order that the routes were declared
via :meth:`pyramid.config.Configurator.add_route`.
When a route configuration is declared, it may contain :term:`route
predicate` arguments.  All route predicates associated with a route
declaration must be ``True`` for the route configuration to be used for a
given request.
given request during a check.  If any predicate in the set of :term:`route
predicate` arguments provided to a route configuration returns ``False``
during a check, that route is skipped and route matching continues through
the ordered set of routes.
If any predicate in the set of :term:`route predicate` arguments provided to
a route configuration returns ``False``, that route is skipped and route
matching continues through the ordered set of routes.
If any route matches, the route matching process stops and the :term:`view
lookup` subsystem takes over to find the most reasonable view callable for
the matched route.  Most often, there's only one view that will match (a view
configured with a ``route_name`` argument matching the matched route).  To
gain a better understanding of how routes and views are associated in a real
application, you can use the ``paster pviews`` command, as documented in
:ref:`displaying_matching_views`.
If no route matches after all route patterns are exhausted, :app:`Pyramid`
falls back to :term:`traversal` to do :term:`resource location` and
@@ -1083,24 +1062,28 @@
  object is decorated with the route-specific interface.
- The fact that the request is decorated with a route-specific interface
  causes the view lookup machinery to always use the view callable registered
  using that interface by the route configuration to service requests that
  match the route pattern.
  causes the :term:`view lookup` machinery to always use the view callable
  registered using that interface by the route configuration to service
  requests that match the route pattern.
In this way, we supply a shortcut to the developer.  Under the hood, the
:term:`resource location` and :term:`view lookup` subsystems provided by
:app:`Pyramid` are still being utilized, but in a way which does not require
a developer to understand either of them in detail.  It also means that we
can allow a developer to combine :term:`URL dispatch` and :term:`traversal`
in various exceptional cases as documented in :ref:`hybrid_chapter`.
As we can see from the above description, technically, URL dispatch doesn't
actually map a URL pattern directly to a view callable.  Instead, URL
dispatch is a :term:`resource location` mechanism.  A :app:`Pyramid`
:term:`resource location` subsystem (i.e., :term:`URL dispatch` or
:term:`traversal`) finds a :term:`resource` object that is the
:term:`context` of a :term:`request`. Once the :term:`context` is determined,
a separate subsystem named :term:`view lookup` is then responsible for
finding and invoking a :term:`view callable` based on information available
in the context and the request.  When URL dispatch is used, the resource
location and view lookup subsystems provided by :app:`Pyramid` are still
being utilized, but in a way which does not require a developer to understand
either of them in detail.
To gain a better understanding of how routes and views are associated in a
real application, you can use the ``paster pviews`` command, as documented
in :ref:`displaying_matching_views`.
If no route is matched using :term:`URL dispatch`, :app:`Pyramid` falls back
to :term:`traversal` to handle the :term:`request`.
References
----------
A tutorial showing how :term:`URL dispatch` can be used to create a
:app:`Pyramid` application exists in :ref:`bfg_sql_wiki_tutorial`.
docs/narr/viewconfig.rst
@@ -235,8 +235,10 @@
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.
  The :term:`view name` required to match this view callable.  A ``name``
  argument is typically only used when your application uses
  :term:`traversal`. 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).
@@ -417,8 +419,7 @@
   from pyramid.view import view_config
   from pyramid.response import Response
   @view_config(name='my_view', request_method='POST', context=MyResource,
                permission='read')
   @view_config(route_name='ok', request_method='POST', permission='read')
   def my_view(request):
       return Response('OK')
@@ -429,9 +430,8 @@
.. code-block:: python
   :linenos:
   config.add_view('mypackage.views.my_view', name='my_view',
                   request_method='POST', context=MyResource,
                   permission='read')
   config.add_view('mypackage.views.my_view', route_name='ok',
                   request_method='POST', permission='read')
All arguments to ``view_config`` may be omitted.  For example:
@@ -499,7 +499,7 @@
   from pyramid.view import view_config
   from pyramid.response import Response
   @view_config(name='edit')
   @view_config(route_name='edit')
   def edit(request):
       return Response('edited!')
@@ -514,7 +514,7 @@
   from pyramid.response import Response
   from pyramid.view import view_config
   @view_config()
   @view_config(route_name='hello')
   class MyView(object):
       def __init__(self, request):
           self.request = request
@@ -539,7 +539,7 @@
       def __call__(self):
           return Response('hello')
   my_view = view_config()(MyView)
   my_view = view_config(route_name='hello')(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
@@ -551,8 +551,8 @@
   from pyramid.view import view_config
   from pyramid.response import Response
   @view_config(name='edit')
   @view_config(name='change')
   @view_config(route_name='edit')
   @view_config(route_name='change')
   def edit(request):
       return Response('edited!')
@@ -570,7 +570,7 @@
       def __init__(self, request):
           self.request = request
       @view_config(name='hello')
       @view_config(route_name='hello')
       def amethod(self):
           return Response('hello')
@@ -592,7 +592,7 @@
   from pyramid.response import Response
   from pyramid.view import view_config
   @view_config(attr='amethod', name='hello')
   @view_config(attr='amethod', route_name='hello')
   class MyView(object):
       def __init__(self, request):
           self.request = request
@@ -624,7 +624,7 @@
   # config is assumed to be an instance of the
   # pyramid.config.Configurator class
   config.add_view(hello_world, name='hello.html')
   config.add_view(hello_world, route_name='hello')
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.
@@ -635,102 +635,6 @@
When you use only :meth:`~pyramid.config.Configurator.add_view` to add view
configurations, you don't need to issue a :term:`scan` in order for the view
configuration to take effect.
.. 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
@@ -753,8 +657,9 @@
   # config is an instance of pyramid.config.Configurator
   config.add_view('myproject.views.add_entry', name='add.html',
                   context='myproject.resources.IBlog', permission='add')
   config.add_route('add', '/add.html', factory='mypackage.Blog')
   config.add_view('myproject.views.add_entry', route_name='add',
                   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
@@ -835,7 +740,7 @@
.. index::
   pair: view configuration; debugging
ebugging View Configuration
Debugging View Configuration
----------------------------
See :ref:`displaying_matching_views` for information about how to display
docs/narr/views.rst
@@ -3,10 +3,10 @@
Views
=====
One of the primary jobs of :app:`Pyramid` is to find and invoke a
:term:`view callable` when a :term:`request` reaches your application.  View
callables are bits of code which do something interesting in response to a
request made to your application.
One of the primary jobs of :app:`Pyramid` is to find and invoke a :term:`view
callable` when a :term:`request` reaches your application.  View callables
are bits of code which do something interesting in response to a request made
to your application.  They are the "meat" of any interesting web application.
.. note:: 
@@ -17,23 +17,10 @@
   that implements a view *callable*, and the process of view
   *lookup*.
The :ref:`urldispatch_chapter`, and :ref:`traversal_chapter` chapters
describes how, using information from the :term:`request`, a
:term:`context` resource is computed.  But the context resource itself
isn't very useful without an associated :term:`view callable`.  A view
callable returns a response to a user, often using the context resource
to do so.
The job of actually locating and invoking the "best" :term:`view callable` is
the job of the :term:`view lookup` subsystem.  The view lookup subsystem
compares the resource supplied by :term:`resource location` and information
in the :term:`request` against :term:`view configuration` statements made by
the developer to choose the most appropriate view callable for a specific
set of circumstances.
This chapter describes how view callables work. In the
:ref:`view_config_chapter` chapter, there are details about performing
view configuration, and a detailed explanation of view lookup.
This chapter describes how view callables should be defined. We'll have to
wait until a following chapter (entitled :ref:`view_config_chapter`) to find
out how we actually tell :app:`Pyramid` to wire up view callables to
particular URL patterns and other request circumstances.
.. index::
   single: view callables
@@ -42,26 +29,20 @@
--------------
View callables are, at the risk of sounding obvious, callable Python
objects. Specifically, view callables can be functions, classes, or
instances that implement an ``__call__`` method (making the
instance callable).
objects. Specifically, view callables can be functions, classes, or instances
that implement an ``__call__`` method (making the instance callable).
View callables must, at a minimum, accept a single argument named
``request``.  This argument represents a :app:`Pyramid` :term:`Request`
object.  A request object encapsulates a WSGI environment provided to
:app:`Pyramid` by the upstream :term:`WSGI` server. As you might expect,
the request object contains everything your application needs to know
about the specific HTTP request being made.
object.  A request object represents a :term:`WSGI` environment provided to
:app:`Pyramid` by the upstream WSGI server. As you might expect, the request
object contains everything your application needs to know about the specific
HTTP request being made.
A view callable's ultimate responsibility is to create a :mod:`Pyramid`
:term:`Response` object. This can be done by creating the response object in
the view callable code and returning it directly, as we will be doing in this
chapter. However, if a view callable does not return a response itself, it
can be configured to use a :term:`renderer` that converts its return value
into a :term:`Response` object. Using renderers is the common way that
templates are used with view callables to generate markup: see the
:ref:`renderers_chapter` chapter for details.  In some cases, a response may
also be generated by raising an exception within a view callable.
:term:`Response` object. This can be done by creating a :term:`Response`
object in the view callable code and returning it directly or by raising
special kinds of exceptions from within the body of a view callable.
.. index::
   single: view calling convention
@@ -160,13 +141,14 @@
object because it inherits from :class:`~pyramid.response.Response`.  For
examples, see :ref:`http_exceptions` and :ref:`http_redirect`.
You can also return objects from view callables that aren't instances of (or
instances of classes which are subclasses of)
:class:`pyramid.response.Response` in various circumstances.  This can be
helpful when writing tests and when attempting to share code between view
callables.  See :ref:`renderers_chapter` for the common way to allow for
this.  A much less common way to allow for view callables to return
non-Response objects is documented in :ref:`using_iresponse`.
.. note::
   You can also return objects from view callables that aren't instances of
   :class:`pyramid.response.Response` in various circumstances.  This can be
   helpful when writing tests and when attempting to share code between view
   callables.  See :ref:`renderers_chapter` for the common way to allow for
   this.  A much less common way to allow for view callables to return
   non-Response objects is documented in :ref:`using_iresponse`.
.. index::
   single: view exceptions