summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/narr/configuration.rst9
-rw-r--r--docs/narr/contextfinding.rst13
-rw-r--r--docs/narr/firstapp.rst10
-rw-r--r--docs/narr/handlers.rst46
-rw-r--r--docs/narr/hybrid.rst72
-rw-r--r--docs/narr/install.rst1
-rw-r--r--docs/narr/models.rst103
-rw-r--r--docs/narr/project.rst13
-rw-r--r--docs/narr/sessions.rst33
-rw-r--r--docs/narr/static.rst76
-rw-r--r--docs/narr/templates.rst210
-rw-r--r--docs/narr/traversal.rst2
-rw-r--r--docs/narr/urldispatch.rst84
-rw-r--r--docs/narr/views.rst406
-rw-r--r--docs/narr/webob.rst21
15 files changed, 596 insertions, 503 deletions
diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst
index 28388ef96..4f26b092a 100644
--- a/docs/narr/configuration.rst
+++ b/docs/narr/configuration.rst
@@ -10,9 +10,9 @@ Each deployment of an application written using :app:`Pyramid` implies a
specific *configuration* of the framework itself. For example, an
application which serves up MP3s for user consumption might plug code into
the framework that manages songs, while an application that manages corporate
-data might plug in code that manages accounting information. :app:`Pyramid`
-refers to the way in which code is plugged in to it for a specific
-application as "configuration".
+data might plug in code that manages accounting information. The way in which
+code is plugged in to :app:`Pyramid`, for a specific application, is referred
+to as "configuration".
Most people understand "configuration" as coarse settings that inform the
high-level operation of a specific application deployment. For instance,
@@ -21,8 +21,7 @@ application startup time as "configuration". :app:`Pyramid` extends this
pattern to application development, using the term "configuration" to express
standardized ways that code gets plugged into a deployment of the framework
itself. When you plug code into the :app:`Pyramid` framework, you are
-"configuring" :app:`Pyramid` for the purpose of creating a particular
-application deployment.
+"configuring" :app:`Pyramid` to create a particular application.
.. index::
single: imperative configuration
diff --git a/docs/narr/contextfinding.rst b/docs/narr/contextfinding.rst
index 770f97d15..691ad7b8e 100644
--- a/docs/narr/contextfinding.rst
+++ b/docs/narr/contextfinding.rst
@@ -51,16 +51,15 @@ requesting user.
that do not provide a notion of a context.
There are two separate :term:`context finding` subsystems in
-:app:`Pyramid`: :term:`traversal` and :term:`URL dispatch`. The
-subsystems are documented within this chapter. They can be used
-separately or they can be combined. Three chapters which follow
-describe :term:`context finding`: :ref:`traversal_chapter`,
+:app:`Pyramid`: :term:`traversal` and :term:`URL dispatch`. They can
+be used separately or they can be combined. Three chapters which
+follow describe :term:`context finding`: :ref:`traversal_chapter`,
:ref:`urldispatch_chapter` and :ref:`hybrid_chapter`.
There is only one :term:`view lookup` subsystem present in
-:app:`Pyramid`. Where appropriate, within this chapter, we
-describe how view lookup interacts with context finding. One chapter
-which follows describes :term:`view lookup`: :ref:`views_chapter`.
+:app:`Pyramid`. Where appropriate, we will describe how view lookup
+interacts with context finding. One chapter which follows describes
+:term:`view lookup`: :ref:`views_chapter`.
Should I Use Traversal or URL Dispatch for Context Finding?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst
index d23a79c4b..b40faee3d 100644
--- a/docs/narr/firstapp.rst
+++ b/docs/narr/firstapp.rst
@@ -137,10 +137,10 @@ passed to the ``Response`` constructor as the *body* of the response. In the
Application Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~
-In the above script, the following code, representing the
-*configuration* of an application which uses the previously defined
-imports and function definitions is placed within the confines of an
-``if`` statement:
+In the above script, the following code represents the *configuration* of this
+simple application. The application is configured using the previously defined
+imports and function definitions, placed within the confines of an ``if``
+statement:
.. code-block:: python
:linenos:
@@ -242,7 +242,7 @@ circumstances which would cause the view configuration's callable to
be invoked. In general, a greater number of predicates supplied along
with a view configuration will more strictly limit the applicability
of its associated view callable. When :app:`Pyramid` processes a
-request, however, the view callable with the *most specific* view
+request, the view callable with the *most specific* view
configuration (the view configuration that matches the most specific
set of predicates) is always invoked.
diff --git a/docs/narr/handlers.rst b/docs/narr/handlers.rst
index 9a5267b2a..f6e658cf0 100644
--- a/docs/narr/handlers.rst
+++ b/docs/narr/handlers.rst
@@ -19,20 +19,21 @@ predicate` to control which method of the handler is called.
:term:`url dispatch`. The concept of a view handler is analogous to a
"controller" in Pylons 1.0.
-The view handler class is initialized by :app:`Pyramid` in the same manner as
-a view class. Its ``__init__`` is called with a request object (see
-:ref:`class_as_view`) when a request enters the system which corresponds with
-a view handler registration made during configuration. A method of the view
-handler class is then called. The method which is called depends on the view
-handler configuration.
-
-The :meth:`pyramid.config.Configurator.add_handler` method will scan
-the handler class and automatically set up views for methods that are
-auto-exposed or were decorated with :class:`~pyramid.view.action`. The
-:class:`~pyramid.view.action` decorator is used to setup additional view
-configuration information for individual class methods, and can be used
-repeatedly for a single method to register multiple view configurations that
-will call that view callable.
+The view handler class is initialized by :app:`Pyramid` in the same
+manner as a view class. Its ``__init__`` is called with a request
+object (see :ref:`class_as_view`) as its argument when a request enters
+the system which corresponds with a view handler registration made
+during configuration. After the view handler class is instantiated, a
+method on the instance is called. The method which is called depends on
+the view handler configuration.
+
+The :meth:`pyramid.config.Configurator.add_handler` method will
+scan the handler class and automatically set up views for methods that
+are auto-exposed, or were decorated with the
+:class:`~pyramid.view.action` decorator. This decorator is used to setup
+additional view configuration information for individual methods of the
+class, and can be used repeatedly for a single view method to
+register multiple view configurations for it.
Here's an example view handler class:
@@ -82,9 +83,9 @@ specific ``action`` name:
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. Other methods in the
-handler class not named 'index' might be called if they were configured to be
-called when the ``action`` name is 'index' as will be seen below.
+'index' in the ``Hello`` handler class to be called. In this case the name
+of the method is the same as the action name: 'index'. However, this
+need not be the case, as we will see below.
.. note::
@@ -175,7 +176,7 @@ Action Decorator
----------------
The :class:`~pyramid.view.action` decorator registers view configuration
-information on the handler method which is used by
+information on the handler method, which is used by
:meth:`~pyramid.config.Configurator.add_handler` to setup the view
configuration.
@@ -210,10 +211,11 @@ Example:
This will register two views that require the ``action`` to be ``index``, with
the additional view predicate requiring a specific request method.
-When a method is decorated multiple times with :class:`~pyramid.view.action`,
-a view configuration will be registered for each call, with the view callable
-being the method decorated. Used with a combination of ``name``, multiple
-URL's can result in different template renderings with the same data.
+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:
diff --git a/docs/narr/hybrid.rst b/docs/narr/hybrid.rst
index b599fefdd..da77a28f0 100644
--- a/docs/narr/hybrid.rst
+++ b/docs/narr/hybrid.rst
@@ -102,7 +102,7 @@ application and a hybrid application:
hybrid application, at least one route will be defined.
- In a purely traversal based application, the root object used is
- global implied by the :term:`root factory` provided at startup
+ global, implied by the :term:`root factory` provided at startup
time; in a hybrid application, the :term:`root` object at which
traversal begins may be varied on a per-route basis.
@@ -207,16 +207,20 @@ the matched route's configuration.
Because the pattern of the above route ends with ``*traverse``, when this
route configuration is matched during a request, :app:`Pyramid`
will attempt to use :term:`traversal` against the :term:`root` object
-implied by the :term:`root factory` implied by the route's
-configuration. Once :term:`traversal` has found a :term:`context`,
+implied by the :term:`root factory` that is implied by the route's
+configuration. Since no ``root_factory`` argument is explicitly specified
+for this route, this will either be the *global* root factory
+for the application, or the *default* root factory.
+Once :term:`traversal` has found a :term:`context`,
:term:`view lookup` will be invoked in almost exactly the same way it
would have been invoked in a "pure" traversal-based application.
-The *default* :term:`root factory` cannot be traversed: it has no
-useful ``__getitem__`` method. So we'll need to associate this route
-configuration with a non-default root factory in order to create a
-useful hybrid application. To that end, let's imagine that we've
-created a root factory that looks like so in a module named
+Let's assume there is no *global* :term:`root factory` configured in
+this application. The *default* :term:`root factory` cannot be traversed:
+it has no useful ``__getitem__`` method. So we'll need to associate
+this route configuration with a custom root factory in order to
+create a useful hybrid application. To that end, let's imagine that
+we've created a root factory that looks like so in a module named
``routes.py``:
.. code-block:: python
@@ -236,7 +240,7 @@ created a root factory that looks like so in a module named
def root_factory(request):
return root
-Above, we've defined a (bogus) graph here that can be traversed, and a
+Above, we've defined a (bogus) graph that can be traversed, and a
``root_factory`` function that can be used as part of a particular
route configuration statement:
@@ -246,20 +250,20 @@ route configuration statement:
config.add_route('home', '{foo}/{bar}/*traverse',
factory='mypackage.routes.root_factory')
-The ``factory`` above points at the function we've defined. It
-will return an instance of the ``Traversable`` class as a root object
-whenever this route is matched. Because the ``Traversable`` object
-we've defined has a ``__getitem__`` method that does something
-nominally useful, and because traversal uses ``__getitem__`` to walk
-the nodes that make up an object graph, using traversal against the
-root object implied by our route statement becomes a reasonable thing
-to do.
+The ``factory`` above points at the function we've defined. It will
+return an instance of the ``Traversable`` class as a root object
+whenever this route is matched. Instances of the``Traversable`` class
+can be used for graph traversal because they have a ``__getitem__``
+method that does something nominally useful. Since traversal uses
+``__getitem__`` to walk the nodes of an object graph, using traversal
+against the root object implied by our route statement is a reasonable
+thing to do.
.. note::
We could have also used our ``root_factory`` callable as the
``root_factory`` argument of the
- :class:`pyramid.config.Configurator` constructor instead
+ :class:`pyramid.config.Configurator` constructor, instead
of associating it with a particular route inside the route's
configuration. Every hybrid route configuration that is matched but
which does *not* name a ``factory`` attribute will use the use
@@ -308,7 +312,7 @@ route's name, in order to indicate that the view should *only be invoked when
the route matches*.
Calls to :meth:`pyramid.config.Configurator.add_view` may pass a
-``route_name`` attribute which refers to the value of an existing route's
+``route_name`` attribute, which refers to the value of an existing route's
``name`` argument. In the above example, the route name is ``home``,
referring to the name of the route defined above it.
@@ -385,7 +389,7 @@ request comes in that causes the route to match in such a way that the
This means that the root object's ``__getitem__`` will be called with
the name ``1`` during the traversal phase. If the ``1`` object
exists, it will become the :term:`context` of the request.
-:ref:`traversal_chapter` has more information about traversal.
+The :ref:`traversal_chapter` chapter has more information about traversal.
If the traversal path contains segment marker names which are not
present in the pattern argument, a runtime error will occur. The
@@ -402,14 +406,15 @@ with this route).
Making Global Views Match
+++++++++++++++++++++++++
-By default, view configurations that don't mention a ``route_name`` will be
-not found by view lookup when a route that mentions a ``*traverse`` in its
-pattern matches. You can make these match forcibly by adding the
-``use_global_views`` flag to the route definition. For example, the
-``myproject.views.bazbuz`` view below will be found if the route named
-``abc`` below is matched and the ``PATH_INFO`` is ``/abc/bazbuz``, even
-though the view configuration statement does not have the
-``route_name="abc"`` attribute.
+By default, only view configurations that mention a ``route_name``
+will be found during view lookup when a route that has a ``*traverse``
+in its pattern matches. You can allow views without a ``route_name``
+attribute to match a route by adding the ``use_global_views`` flag to
+the route definition. For example, the ``myproject.views.bazbuz``
+view below will be found if the route named ``abc`` below is matched
+and the ``PATH_INFO`` is ``/abc/bazbuz``, even though the view
+configuration statement does not have the ``route_name="abc"``
+attribute.
.. code-block:: python
:linenos:
@@ -493,10 +498,10 @@ Can also be spelled like so:
The two spellings are logically equivalent. In fact, the former is
just a syntactical shortcut for the latter.
-Binding Extra Views Against a Route Configuration that Doesn't Have a ``*traverse`` Element In Its Patttern
+Binding Extra Views Against a Route Configuration that Doesn't Have a ``*traverse`` Element In Its Pattern
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Here's another corner case that just makes no sense.
+Here's another corner case that just makes no sense:
.. code-block:: python
:linenos:
@@ -511,7 +516,7 @@ itself (``myproject.views.abc``) will ever be invoked when the route matches,
because the default view is always invoked when a route matches and when no
post-match traversal is performed.
-To make the above view declaration non-useless, the special ``*traverse``
+To make the above view declaration useful, the special ``*traverse``
token must end the route's pattern. For example:
.. code-block:: python
@@ -521,3 +526,8 @@ token must end the route's pattern. For example:
config.add_view('myproject.views.bazbuz', name='bazbuz',
route_name='abc')
+With the above configuration, the ``myproject.views.bazbuz`` view will
+be invoked when the request URI is ``/abc/bazbuz``, assuming there is
+no object contained by the root object with the key ``bazbuz``. A
+different request URI, such as ``/abc/foo/bar``, would invoke the
+default ``myproject.views.abc`` view.
diff --git a/docs/narr/install.rst b/docs/narr/install.rst
index db1cfaf9d..abc4f539c 100644
--- a/docs/narr/install.rst
+++ b/docs/narr/install.rst
@@ -86,7 +86,6 @@ the following commands:
[chrism@vitaminf ~]$ mkdir tmp
[chrism@vitaminf ~]$ mkdir opt
[chrism@vitaminf ~]$ cd tmp
- [chrism@vitaminf tmp]$ cd tmp
[chrism@vitaminf tmp]$ wget \
http://www.python.org/ftp/python/2.6.4/Python-2.6.4.tgz
[chrism@vitaminf tmp]$ tar xvzf Python-2.6.4.tgz
diff --git a/docs/narr/models.rst b/docs/narr/models.rst
index 2c72e766d..79286590a 100644
--- a/docs/narr/models.rst
+++ b/docs/narr/models.rst
@@ -5,8 +5,8 @@ A :term:`model` class is typically a simple Python class defined in a
module. References to these classes and instances of such classes are
omnipresent in :app:`Pyramid`:
-- Model instances make up the graph that :app:`Pyramid` is
- willing to walk over when :term:`traversal` is used.
+- Model instances make up the object graph that :app:`Pyramid`
+ will walk over when :term:`traversal` is used.
- The ``context`` and ``containment`` arguments to
:meth:`pyramid.config.Configurator.add_view` often
@@ -72,7 +72,7 @@ instance.
A model constructor may be essentially any Python object which is
callable, and which returns a model instance. In the above example,
-the ``BlogEntry`` class can be "called", returning a model instance.
+the ``BlogEntry`` class can be called, returning a model instance.
.. index::
single: model interfaces
@@ -130,8 +130,9 @@ that a model implements an interface by using the
``BlogEntry`` model implements the ``IBlogEntry`` interface.
You can also specify that a *particular* model instance provides an
-interface (as opposed to its class). To do so, use the
-:func:`zope.interface.directlyProvides` function:
+interface, as opposed to its class as above, which implies that all
+instances do. To do so, use the :func:`zope.interface.directlyProvides`
+function:
.. code-block:: python
:linenos:
@@ -202,18 +203,18 @@ Defining a Graph of Model Instances for Traversal
When :term:`traversal` is used (as opposed to a purely :term:`url
dispatch` based application), :app:`Pyramid` expects to be able to
traverse a graph composed of model instances. Traversal begins at a
-root model, and descends into the graph recursively via each found
-model's ``__getitem__`` method. :app:`Pyramid` imposes the
+root model instance, and descends into the graph recursively via each
+found model's ``__getitem__`` method. :app:`Pyramid` imposes the
following policy on model instance nodes in the graph:
-- Nodes which contain other nodes (aka "container" nodes) must supply
+- Container nodes (i.e., nodes which contain other nodes) must supply
a ``__getitem__`` method which is willing to resolve a unicode name
to a subobject. If a subobject by that name does not exist in the
container, ``__getitem__`` must raise a :exc:`KeyError`. If a
subobject by that name *does* exist, the container should return the
subobject (another model instance).
-- Nodes which do not contain other nodes (aka "leaf" nodes) must not
+- Leaf nodes, which do not contain other nodes, must not
implement a ``__getitem__``, or if they do, their ``__getitem__``
method must raise a :exc:`KeyError`.
@@ -228,40 +229,17 @@ works against model instances.
Location-Aware Model Instances
------------------------------
-.. sidebar:: Using :mod:`repoze.bfg.traversalwrapper`
-
- If you'd rather not manage the ``__name__`` and ``__parent__``
- attributes of your models "by hand", an add on package named
- :mod:`repoze.bfg.traversalwrapper` can help.
-
- In order to use this helper feature, you must first install the
- :mod:`repoze.bfg.traversalwrapper` package (available via `SVN
- <http://svn.repoze.org/repoze.bfg.traversalwrapper>`_), then
- register its ``ModelGraphTraverser`` as the traversal policy, rather
- than the default :app:`Pyramid` traverser. The package contains
- instructions.
-
- Once :app:`Pyramid` is configured with this feature, you will no
- longer need to manage the ``__parent__`` and ``__name__`` attributes
- on graph objects "by hand". Instead, as necessary, during traversal
- :app:`Pyramid` will wrap each object (even the root object) in a
- ``LocationProxy`` which will dynamically assign a ``__name__`` and a
- ``__parent__`` to the traversed object (based on the last traversed
- object and the name supplied to ``__getitem__``). The root object
- will have a ``__name__`` attribute of ``None`` and a ``__parent__``
- attribute of ``None``.
-
Applications which use :term:`traversal` to locate the :term:`context`
of a view must ensure that the model instances that make up the model
graph are "location aware".
In order for :app:`Pyramid` location, security, URL-generation, and
-traversal functions (such as the functions exposed in
-:ref:`location_module`, :ref:`traversal_module`, and :ref:`url_module`
-as well as certain functions in :ref:`security_module` ) to work
-properly against the instances in an object graph, all nodes in the
-graph must be :term:`location` -aware. This means they must have two
-attributes: ``__parent__`` and ``__name__``.
+traversal functions (i.e., functions in :ref:`location_module`,
+:ref:`traversal_module`, :ref:`url_module` and some in
+:ref:`security_module` ) to work properly against the model instances in
+an object graph, all nodes in the graph must be :term:`location` -aware.
+This means they must have two attributes: ``__parent__`` and
+``__name__``.
The ``__parent__`` attribute should be a reference to the node's
parent model instance in the graph. The ``__name__`` attribute should
@@ -278,15 +256,23 @@ The ``__parent__`` of the root object should be ``None`` and its
__name__ = ''
__parent__ = None
-A node returned from the root item's ``__getitem__`` method should
-have a ``__parent__`` attribute that is a reference to the root
-object, and its ``__name__`` attribute should match the name by which
-it is reachable via the root object's ``__getitem__``. *That*
-object's ``__getitem__`` should return objects that have a
-``__parent__`` attribute that points at that object, and
-``__getitem__``-returned objects should have a ``__name__`` attribute
-that matches the name by which they are retrieved via ``__getitem__``,
-and so on.
+A node returned from the root item's ``__getitem__`` method should have
+a ``__parent__`` attribute that is a reference to the root object, and
+its ``__name__`` attribute should match the name by which it is
+reachable via the root object's ``__getitem__``. A container under the
+root should have a ``__getitem__`` that returns objects with a
+``__parent__`` attribute that points at the container, and these
+subobjects should have a ``__name__`` attribute that matches the name by
+which they are retrieved from the container via ``__getitem__``.
+This pattern continues recursively down the graph.
+
+The ``__parent__`` attributes of each node form a linked list
+that points "upward" toward the root. This is analogous to the
+`..` entry in filesystem directories. If you follow the ``__parent__``
+values from any node in the traversal graph, you will eventually
+come to the root node, just like if you keep executing the
+``cd ..`` filesystem command, eventually you will reach the
+filesystem root directory.
.. warning:: If your root model object has a ``__name__`` argument
that is not ``None`` or the empty string, URLs returned by the
@@ -297,6 +283,29 @@ and so on.
to every path and URL generated (as opposed to a single leading
slash or empty tuple element).
+.. sidebar:: Using :mod:`repoze.bfg.traversalwrapper`
+
+ If you'd rather not manage the ``__name__`` and ``__parent__``
+ attributes of your models "by hand", an add-on package named
+ :mod:`repoze.bfg.traversalwrapper` can help.
+
+ In order to use this helper feature, you must first install the
+ :mod:`repoze.bfg.traversalwrapper` package (available via `SVN
+ <http://svn.repoze.org/repoze.bfg.traversalwrapper>`_), then
+ register its ``ModelGraphTraverser`` as the traversal policy, rather
+ than the default :app:`Pyramid` traverser. The package contains
+ instructions for doing so.
+
+ Once :app:`Pyramid` is configured with this feature, you will no
+ longer need to manage the ``__parent__`` and ``__name__`` attributes
+ on graph objects "by hand". Instead, as necessary, during traversal
+ :app:`Pyramid` will wrap each object (even the root object) in a
+ ``LocationProxy`` which will dynamically assign a ``__name__`` and a
+ ``__parent__`` to the traversed object (based on the last traversed
+ object and the name supplied to ``__getitem__``). The root object
+ will have a ``__name__`` attribute of ``None`` and a ``__parent__``
+ attribute of ``None``.
+
.. index::
single: model API functions
single: url generation (traversal)
diff --git a/docs/narr/project.rst b/docs/narr/project.rst
index 6cfd31c0b..f8a9017db 100644
--- a/docs/narr/project.rst
+++ b/docs/narr/project.rst
@@ -145,6 +145,17 @@ project we name ``MyProject``:
name during ``paster create`` by adding the project name to the
command line, e.g. ``paster create -t pyramid_starter MyProject``.
+.. note:: You may encounter an error when using ``paster create``
+ if a dependent Python package is not installed. This will
+ result in a traceback ending in:
+
+ .. code-block:: text
+
+ pkg_resources.DistributionNotFound: <package name>
+
+ Simply run ``bin/easy_install``, with the missing package
+ name from the error message, to workaround this issue.
+
As a result of invoking the ``paster create`` command, a project is
created in a directory named ``MyProject``. That directory is a
:term:`setuptools` :term:`project` directory from which a setuptools
@@ -760,7 +771,7 @@ also informs Python that the directory which contains it is a *package*.
:term:`context` of the request is an instance of the
:class:`myproject.models.MyModel` class. The first argument to
``add_view`` points at a Python function that does all the work for this
- view, also known as a :term:`view callable` via a :term:`dotted Python
+ view, also known as a :term:`view callable`, via a :term:`dotted Python
name`. The view declaration also names a ``renderer``, which in this case
is a template that will be used to render the result of the view callable.
This particular view declaration points at
diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst
index 8547a92cc..7a0a03384 100644
--- a/docs/narr/sessions.rst
+++ b/docs/narr/sessions.rst
@@ -27,8 +27,8 @@ limitation:
network along which the cookie travels.
- The maximum number of bytes that are storable in a serialized
- representation of the session is fewer than 4000. Only very small
- data sets can be kept in this
+ representation of the session is fewer than 4000. This is
+ suitable only for very small data sets.
It is, however, digitally signed, and thus its data cannot easily be
tampered with.
@@ -62,8 +62,8 @@ Using a Session Object
----------------------
Once a session factory has been configured for your application, you
-can access session objects provided by the session factory by asking
-for the ``session`` attribute of any :term:`request` object. For
+can access session objects provided by the session factory via
+the ``session`` attribute of any :term:`request` object. For
example:
.. code-block:: python
@@ -82,8 +82,7 @@ example:
return Response('Fred was not in the session')
You can use a session much like a Python dictionary. It supports all
-methods of a Python dictionary, and it has three extra attributes, and
-two extra methods.
+dictionary methods, along with some extra attributes, and methods.
Extra attributes:
@@ -98,6 +97,8 @@ Extra methods:
``changed()``
Call this when you mutate a mutable value in the session namespace.
+ See the gotchas below for details on when, and why you should
+ call this.
``invalidate()``
Call this when you want to invalidate the session (dump all data,
@@ -116,15 +117,15 @@ Some gotchas:
pickleable, an error will be raised when the session is serialized.
- If you place a mutable value (for example, a list or a dictionary)
- in a session object, and you subsequently mutate that value, you
- must call the ``changed()`` method of the session object. This is
- because, although the session object can detect when you call its
- data-modifying methods such as ``__setitem__``, ``pop`` and other
- (and thus the session knows it needs to reserialize the session
- data), when you change a mutable object stored in the session
- itself, the session has no way to know that you changed that value.
- When in doubt, call ``changed()`` after you've changed sessioning
- data.
+ in a session object, and you subsequently mutate that value, you must
+ call the ``changed()`` method of the session object. In this case, the
+ session has no way to know that is was modified. However, when you
+ modify a session object directly, such as setting a value (i.e.,
+ ``__setitem__``), or removing a key (e.g., ``del`` or ``pop``), the
+ session will automatically know that it needs to re-serialize its
+ data, thus calling ``changed()`` is unnecessary. There is no harm in
+ calling ``changed()`` in either case, so when in doubt, call it after
+ you've changed sessioning data.
.. index::
single: pyramid_beaker
@@ -154,6 +155,6 @@ session object by implementing a :term:`session factory`. Your
session factory should return a :term:`session`. The interfaces for
both types are available in
:class:`pyramid.interfaces.ISessionFactory` and
-:class:`pyramid.interfaces.ISession`. You might use the cookie
+:class:`pyramid.interfaces.ISession`. You might use the cookie
implementation in the :mod:`pyramid.session` module as inspiration.
diff --git a/docs/narr/static.rst b/docs/narr/static.rst
index 9547e73fc..172fb08d4 100644
--- a/docs/narr/static.rst
+++ b/docs/narr/static.rst
@@ -1,8 +1,8 @@
Static Resources
================
-:app:`Pyramid` makes it possible to serve up "static" (non-dynamic)
-resources from a directory on a filesystem. This chapter describes
+:app:`Pyramid` makes it possible to serve up static
+resources files from a directory on a filesystem. This chapter describes
how to configure :app:`Pyramid` to do so.
.. index::
@@ -20,7 +20,7 @@ application root URL, e.g. ``/static``.
Note that the ``path`` provided to
:meth:`pyramid.config.Configurator.add_static_view` may be a fully
-qualified :term:`resource specification` or an *absolute path*.
+qualified :term:`resource specification`, or an *absolute path*.
Here's an example of a use of
:meth:`pyramid.config.Configurator.add_static_view` that will serve
@@ -100,7 +100,7 @@ provided with a ``name`` argument that is the URL prefix
``http://example.com/images``, subsequent calls to
:func:`pyramid.url.static_url` with paths that start with the ``path``
argument passed to :meth:`pyramid.config.Configurator.add_static_view`
-will generate a URL something like ``http://example.com/logo.png``. The
+will generate a URL something like ``http://example.com/images/logo.png``. The
external webserver listening on ``example.com`` must be itself configured to
respond properly to such a request. The :func:`pyramid.url.static_url` API
is discussed in more detail later in this chapter.
@@ -110,6 +110,25 @@ to :meth:`pyramid.config.Configurator.add_static_view`. Use of the
:ref:`static_directive` ZCML directive is completely equivalent to using
imperative configuration for the same purpose.
+.. note::
+
+ Using :func:`pyramid.url.static_url` in conjunction with a
+ :meth:`pyramid.configuration.Configurator.add_static_view` makes it
+ possible to put static media on a separate webserver during production (if
+ the ``name`` argument to
+ :meth:`pyramid.configuration.Configurator.add_static_view` is a URL),
+ while keeping static media package-internal and served by the development
+ webserver during development (if the ``name`` argument to
+ :meth:`pyramid.configuration.Configurator.add_static_view` is a view
+ name). To create such a circumstance, we suggest using the
+ :attr:`pyramid.registry.Registry.settings` API in conjunction with a
+ setting in the application ``.ini`` file named ``media_location``. Then
+ set the value of ``media_location`` to either a view name or a URL
+ depending on whether the application is being run in development or in
+ production (use a different `.ini`` file for production than you do for
+ development). This is just a suggestion for a pattern; any setting name
+ other than ``media_location`` could be used.
+
.. index::
single: generating static resource urls
single: static resource urls
@@ -133,8 +152,8 @@ For example, let's assume you create a set of static declarations like so:
config.add_static_view(name='static1', path='mypackage:resources/1')
config.add_static_view(name='static2', path='mypackage:resources/2')
-These declarations create URL-accessible directories which have URLs which
-begin, respectively, with ``/static1`` and ``/static2``. The resources in
+These declarations create URL-accessible directories which have URLs that
+begin with ``/static1`` and ``/static2``, respectively. The resources in
the ``resources/1`` directory of the ``mypackage`` package are consulted when
a user visits a URL which begins with ``/static1``, and the resources in the
``resources/2`` directory of the ``mypackage`` package are consulted when a
@@ -178,7 +197,7 @@ instead of a view name. For example, the ``name`` argument may be
.. code-block:: python
:linenos:
- config.add_static_view(name='static1', path='mypackage:images')
+ config.add_static_view(name='http://example.com/images', path='mypackage:images')
Under such a configuration, the URL generated by ``static_url`` for
resources which begin with ``mypackage:images`` will be prefixed with
@@ -206,7 +225,7 @@ The :class:`pyramid.view.static` helper class is used to perform
this task. This class creates an object that is capable acting as a
:app:`Pyramid` view callable which serves static resources from a
directory. For instance, to serve files within a directory located on
-your filesystem at ``/path/to/static/dir`` mounted at the URL path
+your filesystem at ``/path/to/static/dir`` from the URL path
``/static`` in your application, create an instance of the
:class:`pyramid.view.static` class inside a ``static.py`` file in
your application root as below.
@@ -219,13 +238,10 @@ your application root as below.
static_view = static('/path/to/static/dir')
.. note:: the argument to :class:`pyramid.view.static` can also be
- a relative pathname, e.g. ``my/static`` (meaning relative to the
+ a "here-relative" pathname, e.g. ``my/static`` (meaning relative to the
Python package of the module in which the view is being defined).
It can also be a :term:`resource specification`
- (e.g. ``anotherpackage:some/subdirectory``) or it can be a
- "here-relative" path (e.g. ``some/subdirectory``). If the path is
- "here-relative", it is relative to the package of the module in
- which the static view is defined.
+ (e.g. ``anotherpackage:some/subdirectory``).
Subsequently, you may wire this view up to be accessible as ``/static`` using
the :mod:`pyramid.config.Configurator.add_view` method in your
@@ -238,25 +254,33 @@ represents your root object.
config.add_view('mypackage.static.static_view', name='static',
context='mypackage.models.Root')
-In this case, ``mypackage.models.Root`` refers to the class of which your
-:app:`Pyramid` application's root object is an instance.
+In this case, ``mypackage.models.Root`` refers to the class of your
+:app:`Pyramid` application's traversal root object.
-You can also omit the ``context`` argument if you want the name ``static`` to
-be accessible as the static view against any model. This will also allow
-``/static/foo.js`` to work, but it will allow for ``/anything/static/foo.js``
-too, as long as ``anything`` itself is resolvable.
+The context argument above limits where the static view is accessible to
+URL paths directly under the root object. If you omit the ``context``
+argument, then ``static`` will be accessible as the static view against
+any model object in the traversal graph. This will allow
+``/static/foo.js`` to work, but it will also allow for
+``/anything/static/foo.js`` too, as long as ``anything`` can be
+resolved.
Note that you cannot use the :func:`pyramid.url.static_url` API to generate
URLs against resources made accessible by registering a custom static view.
.. warning::
- To ensure that model objects contained in the root don't "shadow"
- your static view (model objects take precedence during traversal),
- or to ensure that your root object's ``__getitem__`` is never
- called when a static resource is requested, you can refer to your
- static resources as registered above in URLs as,
- e.g. ``/@@static/foo.js``. This is completely equivalent to
- ``/static/foo.js``. See :ref:`traversal_chapter` for information
+ When adding a static view to your root object, you need to be
+ careful that there are no model objects contained in the
+ root with the same key as the view name (e.g., ``static``).
+ Model objects take precedence during traversal,
+ thus such a name collision will cause the model to "shadow"
+ your static view. To avoid this issue, and ensure that your
+ root object's ``__getitem__`` is never
+ called when a static resource is requested, you can refer to them
+ unambiguously using the ``@@`` prefix (goggles) in their URLs.
+ For the above examples you could use '/@@static/foo.js'
+ instead of '/static/foo.js' to avoid such shadowing.
+ See :ref:`traversal_chapter` for information
about "goggles" (``@@``).
diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst
index c1c2fe31e..09b9bfc51 100644
--- a/docs/narr/templates.rst
+++ b/docs/narr/templates.rst
@@ -10,7 +10,7 @@ provides add-on templating support through a set of bindings packages.
Out of the box, :app:`Pyramid` provides templating via the :term:`Chameleon`
and :term:`Mako` templating libraries. :term:`Chameleon` provides support for
-two different types of templates: :term:`ZPT` templates and text templates.
+two different types of templates: :term:`ZPT` templates, and text templates.
Before discussing how built-in templates are used in
detail, we'll discuss two ways to render templates within
@@ -22,18 +22,18 @@ configuration.
.. _templates_used_directly:
-Templates Used Directly
------------------------
+Using Templates Directly
+------------------------
The most straightforward way to use a template within
:app:`Pyramid` is to cause it to be rendered directly within a
:term:`view callable`. You may use whatever API is supplied by a
given templating engine to do so.
-:app:`Pyramid` provides various APIs that allow you to render
-templates directly from within a view callable. For example, if there
-is a :term:`Chameleon` ZPT template named ``foo.pt`` in a directory in
-your application named ``templates``, you can render the template from
+:app:`Pyramid` provides various APIs that allow you to render templates
+directly from within a view callable. For example, if there is a
+:term:`Chameleon` ZPT template named ``foo.pt`` in a directory named
+``templates`` in your application, you can render the template from
within the body of a view callable like so:
.. code-block:: python
@@ -58,7 +58,7 @@ within the body of a view callable like so:
rendering tasks. This set of functions works to render templates
for all renderer extensions registered with :app:`Pyramid`.
-The ``sample_view`` :term:`view callable` above returns a
+The ``sample_view`` :term:`view callable` function above returns a
:term:`response` object which contains the body of the
``templates/foo.pt`` template. In this case, the ``templates``
directory should live in the same directory as the module containing
@@ -67,8 +67,8 @@ the ``sample_view`` function. The template author will have the names
comparison purposes.
In the example above, the path ``templates/foo.pt`` is relative to the
-directory in which the file which defines the view configuration
-lives. In this case, this is the directory containing the file that
+directory containing the file which defines the view configuration.
+In this case, this is the directory containing the file that
defines the ``sample_view`` function. Although a renderer path is
usually just a simple relative pathname, a path named as a renderer
can be absolute, starting with a slash on UNIX or a drive letter
@@ -76,18 +76,17 @@ prefix on Windows.
.. warning::
- The ability for a template to be named as a renderer relative to the
- location of the module in which the view callable is defined is limited to
- :term:`Chameleon` templates. Mako templates and other templating system
- bindings work differently. In particular, Mako templates use a "lookup
- path" as defined by the ``mako.directories`` configuration file instead of
- treating relative paths as relative to the current view module. See
- :ref:`mako_templates`.
+ Only :term:`Chameleon` templates support defining a renderer for a
+ template relative to the location of the module where the view
+ callable is defined. Mako templates, and other templating system
+ bindings work differently. In particular, Mako templates use a
+ "lookup path" as defined by the ``mako.directories`` configuration
+ file instead of treating relative paths as relative to the current
+ view module. See :ref:`mako_templates`.
-The path can alternately be a :term:`resource specification` in the
-form ``some.dotted.package_name:relative/path``, making it possible to
-address template resources which live in another package. For
-example:
+The path can alternately be a :term:`resource specification` in the form
+``some.dotted.package_name:relative/path``. This makes it possible to
+address template resources which live in another package. For example:
.. code-block:: python
:linenos:
@@ -118,29 +117,26 @@ In the examples above we pass in a keyword argument named ``request``
representing the current :app:`Pyramid` request. Passing a request
keyword argument will cause the ``render_to_response`` function to
supply the renderer with more correct system values (see
-:ref:`renderer_system_values`), because most of the information
-required to compose proper system values is present in the request.
-If you care about the correct system values being provided to the
-renderer being called (in particular, if your template relies on the
-name ``request`` or ``context``, or if you've configured special
-:term:`renderer globals` make sure to pass ``request`` as a keyword
-argument in every call to to a ``pyramid.renderers.render_*``
-function.
-
-Every view must return a :term:`response` object (except for views
-which use a :term:`renderer` named via view configuration, which we'll
+:ref:`renderer_system_values`), because most of the information required
+to compose proper system values is present in the request. If your
+template relies on the name ``request`` or ``context``, or if you've
+configured special :term:`renderer globals`, make sure to pass
+``request`` as a keyword argument in every call to to a
+``pyramid.renderers.render_*`` function.
+
+Every view must return a :term:`response` object, except for views
+which use a :term:`renderer` named via view configuration (which we'll
see shortly). The :func:`pyramid.renderers.render_to_response`
function is a shortcut function that actually returns a response
-object.
+object. This allows the example view above to simply return the result
+of its call to ``render_to_response()`` directly.
-Obviously not all APIs you might call to get respnonse data will
-return a response object. If you call a "response-ignorant" API that
-returns information you'd like to use as a response (such as when you
-render a template to a string), you must construct your own response
-object as necessary with the string as the body. For example, the
-:func:`pyramid.renderers.render` API returns a string. We can
-manufacture a :term:`response` object directly, and use that string as
-the body of the response:
+Obviously not all APIs you might call to get response data will return a
+response object. For example, you might render one or more templates to
+a string that you want to use as response data. The
+:func:`pyramid.renderers.render` API renders a template to a string. We
+can manufacture a :term:`response` object directly, and use that string
+as the body of the response:
.. code-block:: python
:linenos:
@@ -258,7 +254,7 @@ values are provided in a dictionary to the renderer and include:
``context``
The current :app:`Pyramid` context if ``request`` was provided as
- a keyword argument or ``None``.
+ a keyword argument, or ``None``.
``request``
The request provided as a keyword argument.
@@ -267,31 +263,33 @@ values are provided in a dictionary to the renderer and include:
The renderer name used to perform the rendering,
e.g. ``mypackage:templates/foo.pt``.
-``renderer_info`` An object implementing the
- :class:`pyramid.interfaces.IRendererInfo` interface. Basically, an object
- with the following attributes: ``name``, ``package`` and ``type``.
+``renderer_info``
+ An object implementing the :class:`pyramid.interfaces.IRendererInfo`
+ interface. Basically, an object with the following attributes:
+ ``name``, ``package`` and ``type``.
You can define more values which will be passed to every template
executed as a result of rendering by defining :term:`renderer
globals`.
-What any particular renderer does with them is up to the renderer itself, but
-most template renderers, including Chameleon and Mako renderers, make these
-names available as top-level template variables.
+What any particular renderer does with these system values is up to the
+renderer itself, but most template renderers, including Chameleon and
+Mako renderers, make these names available as top-level template
+variables.
.. _templates_used_as_renderers:
Templates Used as Renderers via Configuration
---------------------------------------------
-Instead of using the :func:`pyramid.renderers.render_to_response`
-API within the body of a view function directly to render a specific
-template to a response, you may associate a template written in a
-supported templating language with a view indirectly by specifying it
-as a :term:`renderer` in *view configuration*.
+An alternative to using :func:`pyramid.renderers.render_to_response`
+to render templates manually in your view callable code, is
+to specify the template as a :term:`renderer` in your
+*view configuration*. This can be done with any of the
+templating languages supported by :app:`Pyramid`.
To use a renderer via view configuration, specify a template
-:term:`resource specification` as the ``renderer`` argument or
+:term:`resource specification` as the ``renderer`` argument, or
attribute to the :term:`view configuration` of a :term:`view
callable`. Then return a *dictionary* from that view callable. The
dictionary items returned by the view callable will be made available
@@ -314,13 +312,11 @@ template renderer:
def my_view(request):
return {'foo':1, 'bar':2}
-.. note:: It is not necessary to supply the ``request`` value as a key
+.. note:: You do not need to supply the ``request`` value as a key
in the dictionary result returned from a renderer-configured view
- callable in order to ensure that the "most correct" system values
- are supplied to the renderer as it is when you use
- :func:`pyramid.renderers.render` or
- :func:`pyramid.renderers.render_to_response`. This is handled
- automatically.
+ callable. :app:`Pyramid` automatically supplies this value for
+ you so that the "most correct" system values are provided to
+ the renderer.
.. warning::
@@ -354,25 +350,25 @@ templates as renderers. See :ref:`available_template_system_bindings`.
.. sidebar:: Why Use A Renderer via View Configuration
Using a renderer in view configuration is usually a better way to
- render templates than using any rendering API directly from within
- a :term:`view callable` because it makes the view callable more
- unit-testable. Views which use templating or rendering APIs
- directly must return a :term:`Response` object. Making testing
- assertions about response objects is typically an indirect process,
- because it means that your test code often needs to somehow parse
- information out of the response body (often HTML). View callables
- which are configured with renderers externally via view
- configuration typically return a dictionary, and making assertions
- about the information is almost always more direct than needing to
- parse HTML. Specifying a renderer from within :term:`ZCML` (as
- opposed to imperatively or via a ``view_config`` decorator, or using a
- template directly from within a view callable) also makes it
- possible for someone to modify the template used to render a view
- without needing to fork your code to do so. See
+ render templates than using any rendering API directly from within a
+ :term:`view callable` because it makes the view callable more
+ unit-testable. Views which use templating or rendering APIs directly
+ must return a :term:`Response` object. Making testing assertions
+ about response objects is typically an indirect process, because it
+ means that your test code often needs to somehow parse information
+ out of the response body (often HTML). View callables configured
+ with renderers externally via view configuration typically return a
+ dictionary, as above. Making assertions about results returned in a
+ dictionary is almost always more direct and straightforward than
+ needing to parse HTML. Specifying a renderer from within
+ :term:`ZCML` (as opposed to imperatively or via a ``view_config``
+ decorator, or using a template directly from within a view callable)
+ also makes it possible for someone to modify the template used to
+ render a view without needing to fork your code to do so. See
:ref:`extending_chapter` for more information.
By default, views rendered via a template renderer return a
-:term:`Response` object which has a *status code* of ``200 OK`` and a
+:term:`Response` object which has a *status code* of ``200 OK``, and a
*content-type* of ``text/html``. To vary attributes of the response
of a view that uses a renderer, such as the content-type, headers, or
status attributes, you must set attributes on the *request* object
@@ -409,13 +405,13 @@ templates is available from `the Chameleon website
:term:`Chameleon` only works on :term:`CPython` platforms and
:term:`Google App Engine`. On :term:`Jython` and other non-CPython
- platforms, you should use Mako (:ref:`mako_templates`) or
+ platforms, you should use Mako (see :ref:`mako_templates`) or
``pyramid_jinja2`` instead. See
:ref:`available_template_system_bindings`.
-Given that there is a :term:`Chameleon` ZPT template named ``foo.pt``
-in a directory in your application named ``templates``, you can render
-the template as a :term:`renderer` like so:
+Given a :term:`Chameleon` ZPT template named ``foo.pt`` in a directory
+in your application named ``templates``, you can render the template as
+a :term:`renderer` like so:
.. code-block:: python
:linenos:
@@ -472,22 +468,21 @@ works in these templates.
Using ZPT Macros in :app:`Pyramid`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When a :term:`renderer` is used to render a template,
-:app:`Pyramid` makes at least two top-level names available to the
-template by default: ``context`` and ``request``. One of the common
-needs in ZPT-based templates is to use one template's "macros" from within
-a different template. In Zope, this is typically handled by
-retrieving the template from the ``context``. But having a hold of
-the context in :app:`Pyramid` is not helpful: templates cannot
-usually be retrieved from models. To use macros in :app:`Pyramid`,
-you need to make the macro template itself available to the rendered
-template by passing the template in which the macro is defined (or even
-the macro itself) *into* the rendered template. To make a macro
-available to the rendered template, you can retrieve a different
-template using the :func:`pyramid.renderers.get_renderer` API,
-and pass it in to the template being rendered. For example, using a
-:term:`view configuration` via a :class:`pyramid.view.view_config`
-decorator that uses a :term:`renderer`:
+When a :term:`renderer` is used to render a template, :app:`Pyramid`
+makes at least two top-level names available to the template by default:
+``context`` and ``request``. One of the common needs in ZPT-based
+templates is to use one template's "macros" from within a different
+template. In Zope, this is typically handled by retrieving the template
+from the ``context``. But the context in :app:`Pyramid` is typically a
+model object, and templates cannot usually be retrieved from models. To
+use macros in :app:`Pyramid`, you need to make the macro template itself
+available to the rendered template by passing the macro template, or
+even the macro itself, *into* the rendered template. To do this you can
+use the :func:`pyramid.renderers.get_renderer` API to retrieve the macro
+template, and pass it into the template being rendered via the dictionary
+returned by the view. For example, using a :term:`view configuration` via a
+:class:`pyramid.view.view_config` decorator that uses a
+:term:`renderer`:
.. code-block:: python
:linenos:
@@ -588,7 +583,7 @@ files showing up in your ``templates`` directory (or otherwise
directly "next" to your templates), it is due to this feature.
If you're using a version control system such as Subversion, you
-should cause it to ignore these files. Here's the contents of the
+should configure it to ignore these files. Here's the contents of the
author's ``svn propedit svn:ignore .`` in each of my ``templates``
directories.
@@ -703,10 +698,10 @@ has built-in bindings for the Mako templating system. The language
definition documentation for Mako templates is available from `the Mako
website <http://www.makotemplates.org/>`_.
-To use a Mako template, given that there is a :term:`Mako` ZPT template named
-``foo.mak`` in the ``templates`` subdirectory in your application package
-named ``mypackage``, you can render the template as a :term:`renderer` like
-so:
+To use a Mako template, given a :term:`Mako` ZPT template file named
+``foo.mak`` in the ``templates`` subdirectory in your application
+package named ``mypackage``, you can configure the template as a
+:term:`renderer` like so:
.. code-block:: python
:linenos:
@@ -757,7 +752,7 @@ look like:
This template doesn't use any advanced features of Mako, only the
``${squiggly}`` replacement syntax for names that are passed in as
-:term:`renderer globals` values. See the `the Mako documentation
+:term:`renderer globals`. See the `the Mako documentation
<http://www.makotemplates.org/>`_ to use more advanced features.
.. index::
@@ -780,7 +775,7 @@ detected, and the template will be reloaded on the next rendering.
usually only desirable during development.
In order to turn on automatic reloading of templates, you can use an
-environment variable setting or a configuration file setting.
+environment variable, or a configuration file setting.
To use an environment variable, start your application under a shell
using the ``BFG_RELOAD_TEMPLATES`` operating system environment
@@ -811,9 +806,8 @@ Available Add-On Template System Bindings
-----------------------------------------
Jinja2 template bindings are available for :app:`Pyramid` in the
-``pyramid_jinja2`` package. It lives in the Pylons version control
-repository at `http://github.com/Pylons/pyramid_jinja2
-<http://github.com/Pylons/pyramid_jinja2>`_. At the time of this writing, it
-has not had a release, but by the time you read this it also might be
-available from :term:`PyPI`.
+``pyramid_jinja2`` package. You can get the latest release of
+this package from the
+`Python package index <http://pypi.python.org/pypi/pyramid_jinja2>`_
+(pypi).
diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst
index 3d109218e..01729c4bd 100644
--- a/docs/narr/traversal.rst
+++ b/docs/narr/traversal.rst
@@ -360,7 +360,7 @@ and a :term:`view name`.
of path segments that come from ``PATH_INFO`` that are "left over"
after traversal has completed.
-Once :term:`context` and :term:`view name` and associated attributes
+Once :term:`context`, :term:`view name`, and associated attributes
such as the :term:`subpath` are located, the job of :term:`traversal`
is finished. It passes back the information it obtained to its
caller, the :app:`Pyramid` :term:`Router`, which subsequently
diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst
index 5d8dae1c5..c84a5ca06 100644
--- a/docs/narr/urldispatch.rst
+++ b/docs/narr/urldispatch.rst
@@ -96,7 +96,7 @@ registry`. Here's an example:
.. versionchanged:: 1.0a4
Prior to 1.0a4, routes allow for a marker starting with a ``:``, for
- example ``/prefix/{one}``. Starting in 1.0a4, this style is deprecated
+ example ``/prefix/:one/:two``. Starting in 1.0a4, this style is deprecated
in favor or ``{}`` usage which allows for additional functionality.
.. index::
@@ -179,12 +179,12 @@ during a request. To do so:
to service requests that match the route pattern.
In this way, we supply a shortcut to the developer. Under the hood,
-:app:`Pyramid` still consumes the :term:`context finding` and
-:term:`view lookup` subsystems provided by :app:`Pyramid`, but in a
-way which does not require that a developer understand either of them
-if he doesn't want or need to. 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`.
+the :term:`context finding` 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`.
.. index::
single: route path pattern syntax
@@ -263,15 +263,15 @@ To capture both segments, two replacement markers can be used:
foo/{name}.{ext}
-The literal path ``/foo/biz.html`` will match the above route pattern, and the
-match result will be ``{'name': 'biz', 'ext': 'html'}``. This occurs because
-the replacement marker ``{name}`` has a literal part of ``.`` between the other
-replacement marker ``:ext``.
+The literal path ``/foo/biz.html`` will match the above route pattern,
+and the match result will be ``{'name': 'biz', 'ext': 'html'}``. This
+occurs because the replacement marker ``{name}`` has a literal part of
+``.`` (period) between the other replacement marker ``{ext}``.
-It is possible to use two replacement markers without any literal characters
-between them, for instance ``/{foo}{bar}``. This would be a nonsensical pattern
-without specifying a custom regular expression to restrict what a marker
-captures.
+It is possible to use two replacement markers without any literal
+characters between them, for instance ``/{foo}{bar}``. However, this
+would be a nonsensical pattern without specifying a custom regular
+expression to restrict what each marker captures.
Segments must contain at least one character in order to match a
segment replacement marker. For example, for the URL ``/abc/``:
@@ -281,7 +281,7 @@ segment replacement marker. For example, for the URL ``/abc/``:
- ``/{foo}/`` will match.
Note that values representing path segments matched with a
-``:segment`` match will be url-unquoted and decoded from UTF-8 into
+``{segment}`` match will be url-unquoted and decoded from UTF-8 into
Unicode within the matchdict. So for instance, the following
pattern:
@@ -358,7 +358,7 @@ matchdicts:
foo/abc/def/a/b/c -> {'baz':'abc', 'bar':'def', 'fizzle': 'a/b/c')}
This occurs because the default regular expression for a marker is ``[^/]+``
-which will match everything up to the first ``/``, while ``{filzzle:.*}`` will
+which will match everything up to the first ``/``, while ``{fizzle:.*}`` will
result in a regular expression match of ``.*`` capturing the remainder into
a single value.
@@ -368,9 +368,9 @@ a single value.
Route Declaration Ordering
~~~~~~~~~~~~~~~~~~~~~~~~~~
-Because route configuration declarations are evaluated in a specific
-order when a request enters the system, route configuration
-declaration ordering is very important.
+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
@@ -390,7 +390,7 @@ be added in the following order:
members/abc
In such a configuration, the ``members/abc`` pattern would *never* be
-matched; this is because the match ordering will always match
+matched. This is because the match ordering will always match
``members/{def}`` first; the route configuration with ``members/abc``
will never be evaluated.
@@ -417,7 +417,7 @@ found via :term:`view lookup`.
factory='myproject.models.root_factory')
The factory can either be a Python object or a :term:`dotted Python name` (a
-string) which points to such a Python oject, as it is above.
+string) which points to such a Python object, as it is above.
In this way, each route can use a different factory, making it
possible to supply a different :term:`context` object to the view
@@ -425,8 +425,8 @@ related to each particular route.
Supplying a different context for each route is useful when you're
trying to use a :app:`Pyramid` :term:`authorization policy` to
-provide declarative "context-sensitive" security checks; each context
-can maintain a separate :term:`ACL`, as in
+provide declarative, "context sensitive" security checks; each context
+can maintain a separate :term:`ACL`, as documented in
:ref:`using_security_with_urldispatch`. It is also useful when you
wish to combine URL dispatch with :term:`traversal` as documented
within :ref:`hybrid_chapter`.
@@ -1080,12 +1080,14 @@ Redirecting to Slash-Appended Routes
------------------------------------
For behavior like Django's ``APPEND_SLASH=True``, use the
-:func:`pyramid.view.append_slash_notfound_view` view as the
-:term:`Not Found view` in your application. When this view is the Not
-Found view (indicating that no view was found), and any routes have
-been defined in the configuration of your application, if the value of
-``PATH_INFO`` does not already end in a slash, and if the value of
-``PATH_INFO`` *plus* a slash matches any route's pattern, it does an
+:func:`pyramid.view.append_slash_notfound_view` view as the :term:`Not
+Found view` in your application. Defining this view as the :term:`Not
+Found view` is a way to automatically redirect requests where the URL
+lacks a trailing slash, but requires one to match the proper route.
+When configured, along with at least one other route in your
+application, this view will be invoked if the value of ``PATH_INFO``
+does not already end in a slash, and if the value of ``PATH_INFO``
+*plus* a slash matches any route's pattern. In this case it does an
HTTP redirect to the slash-appended ``PATH_INFO``.
Let's use an example, because this behavior is a bit magical. If the
@@ -1098,20 +1100,24 @@ your route configuration looks like so:
config.add_route('noslash', 'no_slash', view='myproject.views.no_slash')
config.add_route('hasslash', 'has_slash/', view='myproject.views.has_slash')
+If a request enters the application with the ``PATH_INFO``
+value of ``/has_slash/``, the second route will match. If a request
+enters the application with the ``PATH_INFO`` value of ``/has_slash``,
+a route *will* be found by the slash-appending not found view. An HTTP
+redirect to ``/has_slash/`` will be returned to the user's browser.
+
If a request enters the application with the ``PATH_INFO`` value of
-``/no_slash``, the first route will match. If a request enters the
+``/no_slash``, the first route will match. However, if a request enters the
application with the ``PATH_INFO`` value of ``/no_slash/``, *no* route
-will match, and the slash-appending "not found" view will *not* find a
+will match, and the slash-appending not found view will *not* find a
matching route with an appended slash.
-However, if a request enters the application with the ``PATH_INFO``
-value of ``/has_slash/``, the second route will match. If a request
-enters the application with the ``PATH_INFO`` value of ``/has_slash``,
-a route *will* be found by the slash appending notfound view. An HTTP
-redirect to ``/has_slash/`` will be returned to the user's browser.
+.. warning::
-Note that this will *lose* ``POST`` data information (turning it into
-a GET), so you shouldn't rely on this to redirect POST requests.
+ You **should not** rely on this mechanism to redirect ``POST`` requests.
+ The redirect of the slash-appending not found view will turn a ``POST``
+ request into a ``GET``, losing any ``POST`` data in the original
+ request.
To configure the slash-appending not found view in your application, change
the application's startup configuration, adding the following stanza:
diff --git a/docs/narr/views.rst b/docs/narr/views.rst
index fee341634..8a689be21 100644
--- a/docs/narr/views.rst
+++ b/docs/narr/views.rst
@@ -18,7 +18,7 @@ a request made to your application.
that implements a view *callable*, and the process of view
*lookup*.
-The chapter named :ref:`contextfinding_chapter` describes how, using
+The chapter :ref:`contextfinding_chapter` describes how, using
information from the :term:`request`, a :term:`context` and a
:term:`view name` are computed. But neither the context nor the view
name found are very useful unless those elements can eventually be
@@ -47,15 +47,13 @@ represents a :app:`Pyramid` :term:`Request` object. A request object
encapsulates a WSGI environment as represented to :app:`Pyramid` by the
upstream :term:`WSGI` server.
-A view callable may always return a :mod:`Pyramid` :term:`Response` object
-directly. It may optionally return another arbitrary non-Response value: if a
-view callable returns a non-Response result, the result must be converted into
-a response by the :term:`renderer` associated with the :term:`view
+A view callable can return a :mod:`Pyramid` :term:`Response` object
+directly. It may return another arbitrary non-Response value,
+however, this return value must be converted into a :term:`Response`
+object by the :term:`renderer` associated with the :term:`view
configuration` for the view.
-View callables can be functions, instances, or classes. View
-callables can optionally be defined with an alternate calling
-convention.
+View callables can be functions, instances, or classes.
.. index::
single: view calling convention
@@ -67,7 +65,7 @@ Defining a View Callable as a Function
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The easiest way to define a view callable is to create a function that
-accepts a single argument named ``request`` and which returns a
+accepts a single argument named ``request``, and which returns a
:term:`Response` object. For example, this is a "hello world" view
callable implemented as a function:
@@ -97,10 +95,7 @@ created. Subsequently, that instance's ``__call__`` method is invoked
with no parameters. Views defined as classes must have the following
traits:
-- an ``__init__`` method that accepts a ``request`` as its sole
- positional argument or an ``__init__`` method that accepts two
- arguments: ``request`` and ``context`` as per
- :ref:`request_and_context_view_definitions`.
+- an ``__init__`` method that accepts a ``request`` argument.
- a ``__call__`` method that accepts no parameters and which returns a
response.
@@ -132,75 +127,74 @@ represent the method expected to return a response, you can use an
.. _request_and_context_view_definitions:
-Context-And-Request View Callable Definitions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. sidebar:: Context-And-Request View Callable Definitions
-Usually, view callables are defined to accept only a single argument:
-``request``. However, view callables may alternately be defined as
-classes or functions (or any callable) that accept *two* positional
-arguments: a :term:`context` as the first argument and a
-:term:`request` as the second argument.
+ Usually, view callables are defined to accept only a single argument:
+ ``request``. However, view callables may alternately be defined as
+ classes, functions, or any callable that accept *two* positional
+ arguments: a :term:`context` as the first argument and a
+ :term:`request` as the second argument.
-The :term:`context` and :term:`request` arguments passed to a view
-function defined in this style can be defined as follows:
+ The :term:`context` and :term:`request` arguments passed to a view
+ function defined in this style can be defined as follows:
-context
- An instance of a :term:`context` found via graph :term:`traversal`
- or :term:`URL dispatch`. If the context is found via traversal, it
- will be a :term:`model` object.
+ context
+ An instance of a :term:`context` found via graph :term:`traversal`
+ or :term:`URL dispatch`. If the context is found via traversal, it
+ will be a :term:`model` object.
-request
- A :app:`Pyramid` Request object representing the current WSGI
- request.
+ request
+ A :app:`Pyramid` Request object representing the current WSGI
+ request.
-The following types work as view callables in this style:
+ The following types work as view callables in this style:
-#. Functions that accept two arguments: ``context``, and ``request``,
- e.g.:
+ #. Functions that accept two arguments: ``context``, and ``request``,
+ e.g.:
- .. code-block:: python
- :linenos:
+ .. code-block:: python
+ :linenos:
- from pyramid.response import Response
+ from pyramid.response import Response
- def view(context, request):
- return Response('OK')
+ def view(context, request):
+ return Response('OK')
-#. Classes that have an ``__init__`` method that accepts ``context,
- request`` and a ``__call__`` which accepts no arguments, e.g.:
+ #. Classes that have an ``__init__`` method that accepts ``context,
+ request`` and a ``__call__`` which accepts no arguments, e.g.:
- .. code-block:: python
- :linenos:
+ .. code-block:: python
+ :linenos:
- from pyramid.response import Response
+ from pyramid.response import Response
- class view(object):
- def __init__(self, context, request):
- self.context = context
- self.request = request
+ class view(object):
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
- def __call__(self):
- return Response('OK')
+ def __call__(self):
+ return Response('OK')
-#. Arbitrary callables that have a ``__call__`` method that accepts
- ``context, request``, e.g.:
+ #. Arbitrary callables that have a ``__call__`` method that accepts
+ ``context, request``, e.g.:
- .. code-block:: python
- :linenos:
+ .. code-block:: python
+ :linenos:
- from pyramid.response import Response
+ from pyramid.response import Response
- class View(object):
- def __call__(self, context, request):
- return Response('OK')
- view = View() # this is the view callable
+ class View(object):
+ def __call__(self, context, request):
+ return Response('OK')
+ view = View() # this is the view callable
-This style of calling convention is most useful for :term:`traversal`
-based applications, where the context object is frequently used within
-the view callable code itself.
+ This style of calling convention is most useful for :term:`traversal`
+ based applications, where the context object is frequently used within
+ the view callable code itself.
-No matter which view calling convention is used, the view code always
-has access to the context via ``request.context``.
+ No matter which view calling convention is used, the view code always
+ has access to the context via ``request.context``.
.. index::
single: view response
@@ -288,8 +282,8 @@ and renderers which use templating systems. See also
.. _http_redirect:
-Using a View Callable to Do A HTTP Redirect
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Using a View Callable to Do an HTTP Redirect
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can issue an HTTP redirect from within a view by returning a
particular kind of response.
@@ -308,6 +302,19 @@ See :mod:`pyramid.httpexceptions` for the documentation for the ``HTTPFound``
exception; it also includes other response types that imply other HTTP response
codes, such as ``HTTPUnauthorized`` for ``401 Unauthorized``.
+.. note::
+
+ Although exception types from the :mod:`pyramid.httpexceptions` module are
+ in fact bona fide Python :class:`Exception` types, the :app:`Pyramid` view
+ machinery expects them to be *returned* by a view callable rather than
+ *raised*.
+
+ It is possible, however, in Python 2.5 and above, to configure an
+ *exception view* to catch these exceptions, and return an appropriate
+ :class:`pyramid.response.Response`. The simplest such view could just
+ catch and return the original exception. See :ref:`exception_views` for
+ more details.
+
.. index::
single: renderer
single: view renderer
@@ -379,7 +386,7 @@ Additional renderers can be added to the system as necessary (see
Built-In Renderers
~~~~~~~~~~~~~~~~~~
-Several built-in "renderers" exist in :app:`Pyramid`. These
+Several built-in renderers exist in :app:`Pyramid`. These
renderers can be used in the ``renderer`` attribute of view
configurations.
@@ -429,14 +436,13 @@ attributes by attaching properties to the request. See
``json``: JSON Renderer
+++++++++++++++++++++++
-The ``json`` renderer is a renderer which renders view callable
-results to :term:`JSON`. If a view callable returns a non-Response
-object it is called. It passes the return value through the
+The ``json`` renderer renders view callable
+results to :term:`JSON`. It passes the return value through the
``json.dumps`` standard library function, and wraps the result in a
response object. It also sets the response content-type to
``application/json``.
-Here's an example of a view that returns a dictionary. If the
+Here's an example of a view that returns a dictionary. Since the
``json`` renderer is specified in the configuration for this view, the
view will render the returned dictionary to a JSON serialization:
@@ -561,19 +567,21 @@ attaching properties to the request. See
``*.mak`` or ``*.mako``: Mako Template Renderer
+++++++++++++++++++++++++++++++++++++++++++++++
-The ``Mako`` template renderer is a renderer which renders a Mako template.
+The ``Mako`` template renderer renders views using a Mako template.
When used, the view must return a Response object or a Python *dictionary*.
The dictionary items will then be used in the global template space. If the
-view callable returns anything but a Response object or a dictionary, an error
+view callable returns anything but a Response object, or a dictionary, an error
will be raised.
-When using the ``renderer`` attribute to specify a Mako template, the template
-can be specified in two ways. First, a relative path can be used to name a
-Mako template relative to the configured Mako template directories. Second, a
-:term:`resource specification` can be used to locate a template to render.
-These two styles of naming a template to render also carry through to Mako
-templates, so that Mako template's can inherit using a :term:`resource
-specification` if desired.
+When using a ``renderer`` argument to a :term:`view configuration` to
+specify a Mako template, the value of the ``renderer`` may be a path
+relative to the ``mako.directories`` setting (e.g.
+``some/template.mak``) or, alternately, it may be a :term:`resource
+specification` (e.g. ``apackage:templates/sometemplate.mak``). Mako
+templates may internally inherit other Mako templates using a relative
+filename or a :term:`resource specification` as desired.
+
+XXX Further explanation or link to mako inheritance info
Here's an example view configuration which uses a relative path:
@@ -620,14 +628,13 @@ additional :ref:`mako_template_renderer_settings`.
Varying Attributes of Rendered Responses
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Before a response that is constructed as the result of the use of a
-:term:`renderer` is returned to :app:`Pyramid`, several attributes
-of the request are examined which have the potential to influence
-response behavior.
+Before a response constructed by a :term:`renderer` is returned to
+:app:`Pyramid`, several attributes of the request are examined which
+have the potential to influence response behavior.
View callables that don't directly return a response should set these
-values on the ``request`` object via ``setattr`` within the view
-callable to influence associated response attributes.
+attributes on the ``request`` object via ``setattr`` during their
+execution, to influence associated response attributes.
``response_content_type``
Defines the content-type of the resulting response,
@@ -678,7 +685,7 @@ Adding and Overriding Renderers
New templating systems and serializers can be associated with :app:`Pyramid`
renderer names. To this end, configuration declarations can be made which
-override an existing :term:`renderer factory` and which add a new renderer
+override an existing :term:`renderer factory`, and which add a new renderer
factory.
Renderers can be registered imperatively using the
@@ -707,10 +714,10 @@ to such an object.
Adding a New Renderer
+++++++++++++++++++++
-You may a new renderer by creating and registering a :term:`renderer
+You may add a new renderer by creating and registering a :term:`renderer
factory`.
-A renderer factory implementation is usually a class which has the
+A renderer factory implementation is typically a class with the
following interface:
.. code-block:: python
@@ -739,8 +746,8 @@ factory constructor is available as :class:`pyramid.interfaces.IRendererInfo`.
There are essentially two different kinds of renderer factories:
-- A renderer factory which expects to accept a :term:`resource specification`
- or an absolute path as the ``name`` attribute of the ``info`` object fed to
+- A renderer factory which expects to accept a :term:`resource specification`,
+ or an absolute path, as the ``name`` attribute of the ``info`` object fed to
its constructor. These renderer factories are registered with a ``name``
value that begins with a dot (``.``). These types of renderer factories
usually relate to a file on the filesystem, such as a template.
@@ -770,10 +777,11 @@ Here's an example of the registration of a simple renderer factory via
config.add_renderer(name='amf', factory='my.package.MyAMFRenderer')
-Adding the above code to your application startup configuration will allow
-you to use the ``my.package.MyAMFRenderer`` renderer factory implementation
-in view configurations by referring to it as ``amf`` in the ``renderer``
-attribute of a :term:`view configuration`:
+Adding the above code to your application startup configuration will
+allow you to use the ``my.package.MyAMFRenderer`` renderer factory
+implementation in view configurations. Your application can use this
+renderer by specifying ``amf`` in the ``renderer`` attribute of a
+:term:`view configuration`:
.. code-block:: python
:linenos:
@@ -784,13 +792,12 @@ attribute of a :term:`view configuration`:
def myview(request):
return {'Hello':'world'}
-At startup time, when a :term:`view configuration` is encountered
-which has a ``name`` argument that does not contain a dot, such as the
-above ``amf`` is encountered, the full value of the ``name`` attribute
-is used to construct a renderer from the associated renderer factory.
-In this case, the view configuration will create an instance of an
-``AMFRenderer`` for each view configuration which includes ``amf`` as
-its renderer value. The ``name`` passed to the ``AMFRenderer``
+At startup time, when a :term:`view configuration` is encountered, which
+has a ``name`` attribute that does not contain a dot, the full ``name``
+value is used to construct a renderer from the associated renderer
+factory. In this case, the view configuration will create an instance
+of an ``AMFRenderer`` for each view configuration which includes ``amf``
+as its renderer value. The ``name`` passed to the ``AMFRenderer``
constructor will always be ``amf``.
Here's an example of the registration of a more complicated renderer
@@ -816,17 +823,17 @@ the ``renderer`` attribute of a :term:`view configuration`:
def myview(request):
return {'Hello':'world'}
-When a :term:`view configuration` which has a ``name`` attribute that does
-contain a dot, such as ``templates/mytemplate.jinja2`` above is encountered
-at startup time, the value of the name attribute is split on its final dot.
-The second element of the split is typically the filename extension. This
-extension is used to look up a renderer factory for the configured view.
-Then the value of ``renderer`` is passed to the factory to create a renderer
-for the view. In this case, the view configuration will create an instance
-of a ``Jinja2Renderer`` for each view configuration which includes anything
-ending with ``.jinja2`` as its ``renderer`` value. The ``name`` passed to
-the ``Jinja2Renderer`` constructor will be whatever the user passed as
-``renderer=`` to the view configuration.
+When a :term:`view configuration` is encountered at startup time, which
+has a ``name`` attribute that does contain a dot, the value of the name
+attribute is split on its final dot. The second element of the split is
+typically the filename extension. This extension is used to look up a
+renderer factory for the configured view. Then the value of
+``renderer`` is passed to the factory to create a renderer for the view.
+In this case, the view configuration will create an instance of a
+``Jinja2Renderer`` for each view configuration which includes anything
+ending with ``.jinja2`` in its ``renderer`` value. The ``name`` passed
+to the ``Jinja2Renderer`` constructor will be the full value that was
+set as ``renderer=`` in the view configuration.
See also :ref:`renderer_directive` and
:meth:`pyramid.config.Configurator.add_renderer`.
@@ -861,9 +868,9 @@ After you do this, the :term:`renderer factory` in
``mypackage.pt_renderer`` will be used to render templates which end
in ``.pt``, replacing the default Chameleon ZPT renderer.
-To associate a *default* renderer with *all* view configurations (even ones
-which do not possess a ``renderer`` attribute), use a variation on the
-following (ie. pass ``None`` as the ``name`` attribute to the renderer tag):
+To associate a *default* renderer with *all* view configurations (even
+ones which do not possess a ``renderer`` attribute), pass ``None`` as
+the ``name`` attribute to the renderer tag:
.. code-block:: python
:linenos:
@@ -970,25 +977,24 @@ The above exception view names the ``route_name`` of ``home``, meaning
that it will only be called when the route matched has a name of
``home``. You can therefore have more than one exception view for any
given exception in the system: the "most specific" one will be called
-when the set of request circumstances which match the view
-registration.
+when the set of request circumstances match the view registration.
-The only view predicate that cannot be not be used successfully when
-creating an exception view configuration is ``name``. The name used
-to look up an exception view is always the empty string. Views
-registered as exception views which have a name will be ignored.
+The only view predicate that cannot be used successfully when creating
+an exception view configuration is ``name``. The name used to look up
+an exception view is always the empty string. Views registered as
+exception views which have a name will be ignored.
.. note::
- Normal (non-exception) views registered against a context which
+ Normal (i.e., non-exception) views registered against a context which
inherits from :exc:`Exception` will work normally. When an
- exception view configuraton is processed, *two* views are
+ exception view configuration is processed, *two* views are
registered. One as a "normal" view, the other as an "exception"
view. This means that you can use an exception as ``context`` for a
normal view.
-The feature can be used with any view registration mechanism
-(``@view_config`` decorator, ZCML, or imperative ``add_view`` styles).
+Exception views can be configured with any view registration mechanism:
+``@view_config`` decorator, ZCML, or imperative ``add_view`` styles.
.. index::
single: unicode, views, and forms
@@ -1010,19 +1016,29 @@ implementations, and handling form submission data is a property of
the request implementation. Understanding WebOb's request API is the
key to understanding how to process form submission data.
-There are some defaults that you need to be aware of when trying to handle form
-submission data in a :app:`Pyramid` view. Because having high-order
-(non-ASCII) characters in data contained within form submissions is exceedingly
-common, and because the UTF-8 encoding is the most common encoding used on the
-web for non-ASCII character data, and because working and storing Unicode
-values is much saner than working with and storing bytestrings, :app:`Pyramid`
+There are some defaults that you need to be aware of when trying to
+handle form submission data in a :app:`Pyramid` view. Having high-order
+(i.e., non-ASCII) characters in data contained within form submissions
+is exceedingly common, and the UTF-8 encoding is the most common
+encoding used on the web for character data. Since Unicode values are
+much saner than working with and storing bytestrings, :app:`Pyramid`
configures the :term:`WebOb` request machinery to attempt to decode form
-submission values into Unicode from the UTF-8 character set implicitly. This
-implicit decoding happens when view code obtains form field values via the
-``request.params``, ``request.GET``, or ``request.POST`` APIs (see
-:ref:`request_module` for details about these APIs).
+submission values into Unicode from UTF-8 implicitly.
+This implicit decoding happens when view code obtains form field values
+via the ``request.params``, ``request.GET``, or ``request.POST`` APIs
+(see :ref:`request_module` for details about these APIs).
-For example, let's assume that the following form page is served up to
+.. note::
+ Many people find the difference between Unicode and UTF-8 confusing.
+ Unicode is a standard for representing text that supports most of the
+ world's writing systems. However, there are many ways that Unicode
+ data can be encoded into bytes for transmittal and storage. UTF-8 is
+ a specific encoding for Unicode, that is backwards-compatible with
+ ASCII. This makes UTF-8 very convenient for encoding data where a
+ large subset of that data is ASCII characters, which is largely true
+ on the web. UTF-8 is also the standard character encoding for URLs.
+
+As an example, let's assume that the following form page is served up to
a browser client, and its ``action`` points at some :app:`Pyramid`
view code:
@@ -1069,22 +1085,24 @@ decode already-decoded (``unicode``) values obtained from
firstname = request.params['firstname'].decode('utf-8')
lastname = request.params['lastname'].decode('utf-8')
-For implicit decoding to work reliably, you should ensure that every form you
-render that posts to a :app:`Pyramid` view is rendered via a response that has
-a ``;charset=UTF-8`` in its ``Content-Type`` header; or, as in the form above,
-with a ``meta http-equiv`` tag that implies that the charset is UTF-8 within
-the HTML ``head`` of the page containing the form. This must be done
-explicitly because all known browser clients assume that they should encode
-form data in the character set implied by ``Content-Type`` value of the
-response containing the form when subsequently submitting that form; there is
-no other generally accepted way to tell browser clients which charset to use to
-encode form data. If you do not specify an encoding explicitly, the browser
-client will choose to encode form data in its default character set before
-submitting it. The browser client may have a non-UTF-8 default encoding. If
-such a request is handled by your view code, when the form submission data is
-encoded in a non-UTF8 charset, eventually the request code accessed within your
-view will throw an error when it can't decode some high-order character encoded
-in another character set within form data e.g. when
+For implicit decoding to work reliably, you should ensure that every
+form you render that posts to a :app:`Pyramid` view explicitly defines a
+charset encoding of UTF-8. This can be done via a response that has a
+``;charset=UTF-8`` in its ``Content-Type`` header; or, as in the form
+above, with a ``meta http-equiv`` tag that implies that the charset is
+UTF-8 within the HTML ``head`` of the page containing the form. This
+must be done explicitly because all known browser clients assume that
+they should encode form data in the same character set implied by
+``Content-Type`` value of the response containing the form when
+subsequently submitting that form. There is no other generally accepted
+way to tell browser clients which charset to use to encode form data.
+If you do not specify an encoding explicitly, the browser client will
+choose to encode form data in its default character set before
+submitting it, which may not be UTF-8 as the server expects. If a
+request containing form data encoded in a non-UTF8 charset is handled by
+your view code, eventually the request code accessed within your view
+will throw an error when it can't decode some high-order character
+encoded in another character set within form data, e.g., when
``request.params['somename']`` is accessed.
If you are using the :class:`pyramid.response.Response` class to generate a
@@ -1092,14 +1110,14 @@ response, or if you use the ``render_template_*`` templating APIs, the UTF-8
charset is set automatically as the default via the ``Content-Type`` header.
If you return a ``Content-Type`` header without an explicit charset, a request
will add a ``;charset=utf-8`` trailer to the ``Content-Type`` header value for
-you for response content types that are textual (e.g. ``text/html``,
+you, for response content types that are textual (e.g. ``text/html``,
``application/xml``, etc) as it is rendered. If you are using your own
response object, you will need to ensure you do this yourself.
.. note:: Only the *values* of request params obtained via
``request.params``, ``request.GET`` or ``request.POST`` are decoded
to Unicode objects implicitly in the :app:`Pyramid` default
- configuration. The keys are still strings.
+ configuration. The keys are still (byte) strings.
.. index::
single: view configuration
@@ -1112,7 +1130,7 @@ View Configuration: Mapping a Context to a View
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
-about the set of circumstances which must be true for the view
+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
@@ -1246,6 +1264,10 @@ Non-Predicate Arguments
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.
@@ -1254,7 +1276,7 @@ Predicate Arguments
default view).
``context``
- An object representing Python class that the :term:`context` must be
+ An object representing a Python class that the :term:`context` must be
an instance of, *or* the :term:`interface` that the :term:`context`
must provide in order for this view to be found and called. This
predicate is true when the :term:`context` is an instance of the
@@ -1271,14 +1293,15 @@ Predicate Arguments
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`` usually has 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
+ 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 for when the :term:`triad` includes a
- request object that does not indicate it matched a route.
+ chance of being invoked if no other route was matched. This is when
+ the request object of the :term:`triad` does not indicate it matched
+ any configured route.
``request_type``
This value should be an :term:`interface` that the :term:`request`
@@ -1319,9 +1342,10 @@ Predicate Arguments
``containment``
This value should be a reference to a Python class or
- :term:`interface` that a parent object in the :term:`lineage` must
- provide in order for this view to be found and called. The nodes in
- your object graph must be "location-aware" to use this feature.
+ :term:`interface` that a parent object in the context's
+ :term:`lineage` must provide in order for this view to be found and
+ called. The nodes in your object graph 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
@@ -1480,11 +1504,13 @@ All arguments to ``view_config`` may be omitted. For example:
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 model type, using no permission, registered against
-requests with any request method / request type / request param /
-route name / containment.
+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. To make :app:`Pyramid` process your
+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`:
@@ -1602,7 +1628,7 @@ 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`` as per :ref:`request_and_context_view_definitions`.
+request``.
The method which is decorated must return a :term:`response` or it
must rely on a :term:`renderer` to generate one.
@@ -1721,12 +1747,12 @@ in such a way that the interface is attached to it.
alsoProvides(hello, IHello)
return hello
-Regardless of how you associate an interface with a model instance or a model
+Regardless of how you associate an interface, with a model instance, or a model
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 "models.py", the
-below interface declaration will associate the
-``mypackage.views.hello_world`` view with models that implement (aka provide)
+interface declaration below will associate the
+``mypackage.views.hello_world`` view with models that implement, or provide,
this interface.
.. code-block:: python
@@ -1741,11 +1767,13 @@ Any time a model 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 that views registered against a model class take precedence over views
-registered for any interface the model class implements when an ambiguity
-arises. If a view is registered for both the class type of the context and
-an interface implemented by the context's class, the view registered for the
-context's class will "win".
+Note, in cases where a view is registered against a model class, and a
+view is also registered against an interface that the model class
+implements, an ambiguity arises. Views registered for the model class
+take precedence over any views registered for any interface the model
+class implements. Thus, if a view is registered for both the class type
+of the context and an interface implemented by the context's class, the
+view registered for the context's class will "win".
For more information about defining models with interfaces for use within
view configuration, see :ref:`models_which_implement_interfaces`.
@@ -1759,12 +1787,22 @@ view configuration, see :ref:`models_which_implement_interfaces`.
Configuring View Security
~~~~~~~~~~~~~~~~~~~~~~~~~
+<<<<<<< HEAD
+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` before the view
+function is actually called. Here's an example of specifying a
+permission in a view configuration using
+:meth:`pyramid.configuration.Configurator.add_view`:
+=======
If a :term:`authorization policy` is active, any :term:`permission` attached
to a :term:`view configuration` found during view lookup will be consulted to
ensure that the currently authenticated user possesses that permission
against the :term:`context` 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`:
+>>>>>>> fee38663daccc0130d0c34dbc5a14e67bef2e183
.. code-block:: python
:linenos:
@@ -1774,11 +1812,11 @@ Here's an example of specifying a permission in a view configuration using
config.add_view('myproject.views.add_entry', name='add.html',
context='myproject.models.IBlog', permission='add')
-When an authentication 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` and an
-authorization policy is enabled. Instead the :term:`forbidden view` result
-will be returned to the client as per :ref:`protecting_views`.
+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: view lookup
@@ -1792,7 +1830,7 @@ View Lookup and Invocation
finding an invoking a :term:`view callable`. The view lookup
subsystem is passed a :term:`context`, a :term:`view name`, and the
:term:`request` object. These three bits of information are referred
-to within this chapter as a :term:`triad`.
+to within this chapter as the :term:`triad`.
:term:`View configuration` information stored within in the
:term:`application registry` is compared against a triad by the view
@@ -1817,7 +1855,7 @@ 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 which has predicates which allow it to be
+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
@@ -1839,5 +1877,5 @@ misconfiguration. To debug these errors, use the
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.
+more information about how, and where to set these values.
diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst
index c4805df8d..83d096a57 100644
--- a/docs/narr/webob.rst
+++ b/docs/narr/webob.rst
@@ -111,8 +111,8 @@ Special Attributes Added to the Request by :app:`Pyramid`
In addition to the standard :term:`WebOb` attributes, :app:`Pyramid`
adds special attributes to every request: ``context``, ``registry``,
-``root``, ``subpath``, ``traversed``, ``view_name``, ``virtual_root``
-, ``virtual_root_path``, ``session``, and ``tmpl_context``. These
+``root``, ``subpath``, ``traversed``, ``view_name``, ``virtual_root``,
+``virtual_root_path``, ``session``, and ``tmpl_context``. These
attributes are documented further within the
:class:`pyramid.request.Request` API documentation.
@@ -183,7 +183,7 @@ only a few you'll use often:
``req.get_response(wsgi_application)``:
This method calls the given WSGI application with this request,
and returns a `Response`_ object. You can also use this for
- subrequests or testing.
+ subrequests, or testing.
.. index::
single: request (and unicode)
@@ -203,8 +203,8 @@ attribute.
If it is set, then ``req.POST``, ``req.GET``, ``req.params``, and
``req.cookies`` will contain unicode strings. Each has a
-corresponding ``req.str_*`` (like ``req.str_POST``) that is always
-``str`` and never unicode.
+corresponding ``req.str_*`` (e.g., ``req.str_POST``) that is always
+a ``str``, and never unicode.
More Details
++++++++++++
@@ -213,9 +213,9 @@ More detail about the request object API is available in:
- The :class:`pyramid.request.Request` API documentation.
-- The `WebOb documentation <http://pythonpaste.org/webob>`_ . All
+- The `WebOb documentation <http://pythonpaste.org/webob>`_. All
methods and attributes of a ``webob.Request`` documented within the
- WebOb documentation will work against request objects created by
+ WebOb documentation will work with request objects created by
:app:`Pyramid`.
.. index::
@@ -231,8 +231,9 @@ for its original location: ``webob.Response``.
A response object has three fundamental parts:
``response.status``:
- The response code plus message, like ``'200 OK'``. To set the
- code without the reason, use ``response.status_int = 200``.
+ The response code plus reason message, like ``'200 OK'``. To set
+ the code without a message, use ``status_int``, i.e.:
+ ``response.status_int = 200``.
``response.headerlist``:
A list of all the headers, like ``[('Content-Type',
@@ -325,7 +326,7 @@ Exception Responses
To facilitate error responses like ``404 Not Found``, the module
:mod:`webob.exc` contains classes for each kind of error response. These
-include boring but appropriate error bodies. The exceptions exposed by this
+include boring, but appropriate error bodies. The exceptions exposed by this
module, when used under :app:`Pyramid`, should be imported from the
:mod:`pyramid.httpexceptions` "facade" module. This import location is merely
a facade for the original location of these exceptions: ``webob.exc``.