summaryrefslogtreecommitdiff
path: root/docs/narr/hybrid.rst
diff options
context:
space:
mode:
authorSteve Piercy <web@stevepiercy.com>2015-11-02 00:09:06 -0800
committerSteve Piercy <web@stevepiercy.com>2015-11-02 00:09:06 -0800
commit50d32d442b81f0e06bf3eee034f7b2eb8cdfb2ec (patch)
treeabe37acc8c81a89074b69f1f467001b2f1deb100 /docs/narr/hybrid.rst
parentcfd8ccfce67b89fab9095ac41ac3ca85f9c0da0e (diff)
downloadpyramid-50d32d442b81f0e06bf3eee034f7b2eb8cdfb2ec.tar.gz
pyramid-50d32d442b81f0e06bf3eee034f7b2eb8cdfb2ec.tar.bz2
pyramid-50d32d442b81f0e06bf3eee034f7b2eb8cdfb2ec.zip
- remove deprecated section in docs (Closes #2067)
- minor grammar, rewrap to 79 columns
Diffstat (limited to 'docs/narr/hybrid.rst')
-rw-r--r--docs/narr/hybrid.rst539
1 files changed, 217 insertions, 322 deletions
diff --git a/docs/narr/hybrid.rst b/docs/narr/hybrid.rst
index 1c324d22b..ff26d52ec 100644
--- a/docs/narr/hybrid.rst
+++ b/docs/narr/hybrid.rst
@@ -12,28 +12,26 @@ dispatch. However, to solve a limited set of problems, it's useful to use
.. warning::
Reasoning about the behavior of a "hybrid" URL dispatch + traversal
- application can be challenging. To successfully reason about using
- URL dispatch and traversal together, you need to understand URL
- pattern matching, root factories, and the :term:`traversal`
- algorithm, and the potential interactions between them. Therefore,
- we don't recommend creating an application that relies on hybrid
- behavior unless you must.
+ application can be challenging. To successfully reason about using URL
+ dispatch and traversal together, you need to understand URL pattern
+ matching, root factories, and the :term:`traversal` algorithm, and the
+ potential interactions between them. Therefore, we don't recommend creating
+ an application that relies on hybrid behavior unless you must.
A Review of Non-Hybrid Applications
-----------------------------------
-When used according to the tutorials in its documentation
-:app:`Pyramid` is a "dual-mode" framework: the tutorials explain
-how to create an application in terms of using either :term:`url
-dispatch` *or* :term:`traversal`. This chapter details how you might
-combine these two dispatch mechanisms, but we'll review how they work
-in isolation before trying to combine them.
+When used according to the tutorials in its documentation, :app:`Pyramid` is a
+"dual-mode" framework: the tutorials explain how to create an application in
+terms of using either :term:`URL dispatch` *or* :term:`traversal`. This
+chapter details how you might combine these two dispatch mechanisms, but we'll
+review how they work in isolation before trying to combine them.
URL Dispatch Only
~~~~~~~~~~~~~~~~~
-An application that uses :term:`url dispatch` exclusively to map URLs to code
-will often have statements like this within application startup
+An application that uses :term:`URL dispatch` exclusively to map URLs to code
+will often have statements like this within its application startup
configuration:
.. code-block:: python
@@ -48,11 +46,11 @@ configuration:
config.add_view('myproject.views.bazbuz', route_name='bazbuz')
Each :term:`route` corresponds to one or more view callables. Each view
-callable is associated with a route by passing a ``route_name`` parameter
-that matches its name during a call to
-:meth:`~pyramid.config.Configurator.add_view`. When a route is matched
-during a request, :term:`view lookup` is used to match the request to its
-associated view callable. The presence of calls to
+callable is associated with a route by passing a ``route_name`` parameter that
+matches its name during a call to
+:meth:`~pyramid.config.Configurator.add_view`. When a route is matched during
+a request, :term:`view lookup` is used to match the request to its associated
+view callable. The presence of calls to
:meth:`~pyramid.config.Configurator.add_route` signify that an application is
using URL dispatch.
@@ -72,12 +70,11 @@ declarations that look like this:
When the above configuration is applied to an application, the
``mypackage.views.foobar`` view callable above will be called when the URL
-``/foobar`` is visited. Likewise, the view ``mypackage.views.bazbuz`` will
-be called when the URL ``/bazbuz`` is visited.
+``/foobar`` is visited. Likewise, the view ``mypackage.views.bazbuz`` will be
+called when the URL ``/bazbuz`` is visited.
Typically, an application that uses traversal exclusively won't perform any
-calls to :meth:`pyramid.config.Configurator.add_route` in its startup
-code.
+calls to :meth:`pyramid.config.Configurator.add_route` in its startup code.
.. index::
single: hybrid applications
@@ -85,149 +82,139 @@ code.
Hybrid Applications
-------------------
-Either traversal or url dispatch alone can be used to create a
-:app:`Pyramid` application. However, it is also possible to
-combine the concepts of traversal and url dispatch when building an
-application: the result is a hybrid application. In a hybrid
-application, traversal is performed *after* a particular route has
-matched.
-
-A hybrid application is a lot more like a "pure" traversal-based
-application than it is like a "pure" URL-dispatch based application.
-But unlike in a "pure" traversal-based application, in a hybrid
-application, :term:`traversal` is performed during a request after a
-route has already matched. This means that the URL pattern that
-represents the ``pattern`` argument of a route must match the
-``PATH_INFO`` of a request, and after the route pattern has matched,
-most of the "normal" rules of traversal with respect to :term:`resource
-location` and :term:`view lookup` apply.
+Either traversal or URL dispatch alone can be used to create a :app:`Pyramid`
+application. However, it is also possible to combine the concepts of traversal
+and URL dispatch when building an application, the result of which is a hybrid
+application. In a hybrid application, traversal is performed *after* a
+particular route has matched.
+
+A hybrid application is a lot more like a "pure" traversal-based application
+than it is like a "pure" URL-dispatch based application. But unlike in a "pure"
+traversal-based application, in a hybrid application :term:`traversal` is
+performed during a request after a route has already matched. This means that
+the URL pattern that represents the ``pattern`` argument of a route must match
+the ``PATH_INFO`` of a request, and after the route pattern has matched, most
+of the "normal" rules of traversal with respect to :term:`resource location`
+and :term:`view lookup` apply.
There are only four real differences between a purely traversal-based
application and a hybrid application:
-- In a purely traversal based application, no routes are defined; in a
- hybrid application, at least one route will be defined.
+- In a purely traversal-based application, no routes are defined. In a 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
- time; in a hybrid application, the :term:`root` object at which
- traversal begins may be varied on a per-route basis.
+- In a purely traversal-based application, the root object used is 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.
-- In a purely traversal-based application, the ``PATH_INFO`` of the
- underlying :term:`WSGI` environment is used wholesale as a traversal
- path; in a hybrid application, the traversal path is not the entire
- ``PATH_INFO`` string, but a portion of the URL determined by a
- matching pattern in the matched route configuration's pattern.
+- In a purely traversal-based application, the ``PATH_INFO`` of the underlying
+ :term:`WSGI` environment is used wholesale as a traversal path. In a hybrid
+ application, the traversal path is not the entire ``PATH_INFO`` string, but a
+ portion of the URL determined by a matching pattern in the matched route
+ configuration's pattern.
-- In a purely traversal based application, view configurations which
- do not mention a ``route_name`` argument are considered during
- :term:`view lookup`; in a hybrid application, when a route is
- matched, only view configurations which mention that route's name as
- a ``route_name`` are considered during :term:`view lookup`.
+- In a purely traversal-based application, view configurations which do not
+ mention a ``route_name`` argument are considered during :term:`view lookup`.
+ In a hybrid application, when a route is matched, only view configurations
+ which mention that route's name as a ``route_name`` are considered during
+ :term:`view lookup`.
-More generally, a hybrid application *is* a traversal-based
-application except:
+More generally, a hybrid application *is* a traversal-based application except:
-- the traversal *root* is chosen based on the route configuration of
- the route that matched instead of from the ``root_factory`` supplied
- during application startup configuration.
+- the traversal *root* is chosen based on the route configuration of the route
+ that matched, instead of from the ``root_factory`` supplied during
+ application startup configuration.
-- the traversal *path* is chosen based on the route configuration of
- the route that matched rather than from the ``PATH_INFO`` of a
- request.
+- the traversal *path* is chosen based on the route configuration of the route
+ that matched, rather than from the ``PATH_INFO`` of a request.
-- the set of views that may be chosen during :term:`view lookup` when
- a route matches are limited to those which specifically name a
- ``route_name`` in their configuration that is the same as the
- matched route's ``name``.
+- the set of views that may be chosen during :term:`view lookup` when a route
+ matches are limited to those which specifically name a ``route_name`` in
+ their configuration that is the same as the matched route's ``name``.
-To create a hybrid mode application, use a :term:`route configuration`
-that implies a particular :term:`root factory` and which also includes
-a ``pattern`` argument that contains a special dynamic part: either
-``*traverse`` or ``*subpath``.
+To create a hybrid mode application, use a :term:`route configuration` that
+implies a particular :term:`root factory` and which also includes a ``pattern``
+argument that contains a special dynamic part: either ``*traverse`` or
+``*subpath``.
The Root Object for a Route Match
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-A hybrid application implies that traversal is performed during a
-request after a route has matched. Traversal, by definition, must
-always begin at a root object. Therefore it's important to know
-*which* root object will be traversed after a route has matched.
+A hybrid application implies that traversal is performed during a request after
+a route has matched. Traversal, by definition, must always begin at a root
+object. Therefore it's important to know *which* root object will be traversed
+after a route has matched.
-Figuring out which :term:`root` object results from a particular route
-match is straightforward. When a route is matched:
+Figuring out which :term:`root` object results from a particular route match is
+straightforward. When a route is matched:
-- If the route's configuration has a ``factory`` argument which
- points to a :term:`root factory` callable, that callable will be
- called to generate a :term:`root` object.
+- If the route's configuration has a ``factory`` argument which points to a
+ :term:`root factory` callable, that callable will be called to generate a
+ :term:`root` object.
-- If the route's configuration does not have a ``factory``
- argument, the *global* :term:`root factory` will be called to
- generate a :term:`root` object. The global root factory is the
- callable implied by the ``root_factory`` argument passed to the
- :class:`~pyramid.config.Configurator` at application
- startup time.
+- If the route's configuration does not have a ``factory`` argument, the
+ *global* :term:`root factory` will be called to generate a :term:`root`
+ object. The global root factory is the callable implied by the
+ ``root_factory`` argument passed to the :class:`~pyramid.config.Configurator`
+ at application startup time.
- If a ``root_factory`` argument is not provided to the
- :class:`~pyramid.config.Configurator` at startup time, a
- *default* root factory is used. The default root factory is used to
- generate a root object.
+ :class:`~pyramid.config.Configurator` at startup time, a *default* root
+ factory is used. The default root factory is used to generate a root object.
.. note::
Root factories related to a route were explained previously within
- :ref:`route_factories`. Both the global root factory and default
- root factory were explained previously within
- :ref:`the_resource_tree`.
+ :ref:`route_factories`. Both the global root factory and default root
+ factory were explained previously within :ref:`the_resource_tree`.
.. index::
pair: hybrid applications; *traverse route pattern
.. _using_traverse_in_a_route_pattern:
-Using ``*traverse`` In a Route Pattern
+Using ``*traverse`` in a Route Pattern
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-A hybrid application most often implies the inclusion of a route
-configuration that contains the special token ``*traverse`` at the end
-of a route's pattern:
+A hybrid application most often implies the inclusion of a route configuration
+that contains the special token ``*traverse`` at the end of a route's pattern:
.. code-block:: python
:linenos:
config.add_route('home', '{foo}/{bar}/*traverse')
-A ``*traverse`` token at the end of the pattern in a route's
-configuration implies a "remainder" *capture* value. When it is used,
-it will match the remainder of the path segments of the URL. This
-remainder becomes the path used to perform traversal.
+A ``*traverse`` token at the end of the pattern in a route's configuration
+implies a "remainder" *capture* value. When it is used, it will match the
+remainder of the path segments of the URL. This remainder becomes the path
+used to perform traversal.
.. note::
- The ``*remainder`` route pattern syntax is explained in more
- detail within :ref:`route_pattern_syntax`.
+ The ``*remainder`` route pattern syntax is explained in more detail within
+ :ref:`route_pattern_syntax`.
A hybrid mode application relies more heavily on :term:`traversal` to do
:term:`resource location` and :term:`view lookup` than most examples indicate
within :ref:`urldispatch_chapter`.
-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` that is implied by the route's configuration. Since no
+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` 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` resource,
+either be the *global* root factory for the application, or the *default* root
+factory. Once :term:`traversal` has found a :term:`context` resource,
:term:`view lookup` will be invoked in almost exactly the same way it would
have been invoked in a "pure" traversal-based application.
-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``:
+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
:linenos:
@@ -246,7 +233,7 @@ we've created a root factory that looks like so in a module named
def root_factory(request):
return root
-Above, we've defined a (bogus) resource tree that can be traversed, and a
+Above we've defined a (bogus) resource tree that can be traversed, and a
``root_factory`` function that can be used as part of a particular route
configuration statement:
@@ -256,8 +243,8 @@ 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 ``Resource`` class as a root object whenever this route is
+The ``factory`` above points at the function we've defined. It will return an
+instance of the ``Resource`` class as a root object whenever this route is
matched. Instances of the ``Resource`` class can be used for tree traversal
because they have a ``__getitem__`` method that does something nominally
useful. Since traversal uses ``__getitem__`` to walk the resources of a
@@ -266,39 +253,37 @@ statement is a reasonable thing to do.
.. note::
- We could have also used our ``root_factory`` function as the
- ``root_factory`` argument of the
- :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
- global ``root_factory`` function to generate a root object.
+ We could have also used our ``root_factory`` function as the ``root_factory``
+ argument of the :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 global ``root_factory`` function to
+ generate a root object.
-When the route configuration named ``home`` above is matched during a
-request, the matchdict generated will be based on its pattern:
+When the route configuration named ``home`` above is matched during a request,
+the matchdict generated will be based on its pattern:
``{foo}/{bar}/*traverse``. The "capture value" implied by the ``*traverse``
element in the pattern will be used to traverse the resource tree in order to
find a context resource, starting from the root object returned from the root
factory. In the above example, the :term:`root` object found will be the
instance named ``root`` in ``routes.py``.
-If the URL that matched a route with the pattern ``{foo}/{bar}/*traverse``,
-is ``http://example.com/one/two/a/b/c``, the traversal path used
-against the root object will be ``a/b/c``. As a result,
-:app:`Pyramid` will attempt to traverse through the edges ``'a'``,
-``'b'``, and ``'c'``, beginning at the root object.
+If the URL that matched a route with the pattern ``{foo}/{bar}/*traverse`` is
+``http://example.com/one/two/a/b/c``, the traversal path used against the root
+object will be ``a/b/c``. As a result, :app:`Pyramid` will attempt to traverse
+through the edges ``'a'``, ``'b'``, and ``'c'``, beginning at the root object.
-In our above example, this particular set of traversal steps will mean that
-the :term:`context` resource of the view would be the ``Resource`` object
-we've named ``'c'`` in our bogus resource tree and the :term:`view name`
-resulting from traversal will be the empty string; if you need a refresher
-about why this outcome is presumed, see :ref:`traversal_algorithm`.
+In our above example, this particular set of traversal steps will mean that the
+:term:`context` resource of the view would be the ``Resource`` object we've
+named ``'c'`` in our bogus resource tree, and the :term:`view name` resulting
+from traversal will be the empty string. If you need a refresher about why
+this outcome is presumed, see :ref:`traversal_algorithm`.
-At this point, a suitable view callable will be found and invoked
-using :term:`view lookup` as described in :ref:`view_configuration`,
-but with a caveat: in order for view lookup to work, we need to define
-a view configuration that will match when :term:`view lookup` is
-invoked after a route matches:
+At this point, a suitable view callable will be found and invoked using
+:term:`view lookup` as described in :ref:`view_configuration`, but with a
+caveat: in order for view lookup to work, we need to define a view
+configuration that will match when :term:`view lookup` is invoked after a route
+matches:
.. code-block:: python
:linenos:
@@ -307,28 +292,28 @@ invoked after a route matches:
factory='mypackage.routes.root_factory')
config.add_view('mypackage.views.myview', route_name='home')
-Note that the above call to
-:meth:`~pyramid.config.Configurator.add_view` includes a ``route_name``
-argument. View configurations that include a ``route_name`` argument are
-meant to associate a particular view declaration with a route, using the
-route's name, in order to indicate that the view should *only be invoked when
-the route matches*.
+Note that the above call to :meth:`~pyramid.config.Configurator.add_view`
+includes a ``route_name`` argument. View configurations that include a
+``route_name`` argument are meant to associate a particular view declaration
+with a route, using the 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
-``name`` argument. In the above example, the route name is ``home``,
-referring to the name of the route defined above it.
+``name`` argument. In the above example, the route name is ``home``, referring
+to the name of the route defined above it.
-The above ``mypackage.views.myview`` view callable will be invoked when:
+The above ``mypackage.views.myview`` view callable will be invoked when the
+following conditions are met:
-- the route named "home" is matched
+- The route named "home" is matched.
-- the :term:`view name` resulting from traversal is the empty string.
+- The :term:`view name` resulting from traversal is the empty string.
-- the :term:`context` resource is any object.
+- The :term:`context` resource is any object.
-It is also possible to declare alternate views that may be invoked
-when a hybrid route is matched:
+It is also possible to declare alternative views that may be invoked when a
+hybrid route is matched:
.. code-block:: python
:linenos:
@@ -340,37 +325,37 @@ when a hybrid route is matched:
name='another')
The ``add_view`` call for ``mypackage.views.another_view`` above names a
-different view and, more importantly, a different :term:`view name`. The
-above ``mypackage.views.another_view`` view will be invoked when:
+different view and, more importantly, a different :term:`view name`. The above
+``mypackage.views.another_view`` view will be invoked when the following
+conditions are met:
-- the route named "home" is matched
+- The route named "home" is matched.
-- the :term:`view name` resulting from traversal is ``another``.
+- The :term:`view name` resulting from traversal is ``another``.
-- the :term:`context` resource is any object.
+- The :term:`context` resource is any object.
For instance, if the URL ``http://example.com/one/two/a/another`` is provided
to an application that uses the previously mentioned resource tree, the
-``mypackage.views.another`` view callable will be called instead of the
-``mypackage.views.myview`` view callable because the :term:`view name` will
-be ``another`` instead of the empty string.
+``mypackage.views.another_view`` view callable will be called instead of the
+``mypackage.views.myview`` view callable because the :term:`view name` will be
+``another`` instead of the empty string.
More complicated matching can be composed. All arguments to *route*
-configuration statements and *view* configuration statements are
-supported in hybrid applications (such as :term:`predicate`
-arguments).
+configuration statements and *view* configuration statements are supported in
+hybrid applications (such as :term:`predicate` arguments).
-Using the ``traverse`` Argument In a Route Definition
+Using the ``traverse`` Argument in a Route Definition
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Rather than using the ``*traverse`` remainder marker in a pattern, you
-can use the ``traverse`` argument to the
-:meth:`~pyramid.config.Configurator.add_route` method.
+Rather than using the ``*traverse`` remainder marker in a pattern, you can use
+the ``traverse`` argument to the :meth:`~pyramid.config.Configurator.add_route`
+method.
-When you use the ``*traverse`` remainder marker, the traversal path is
-limited to being the remainder segments of a request URL when a route
-matches. However, when you use the ``traverse`` argument or
-attribute, you have more control over how to compose a traversal path.
+When you use the ``*traverse`` remainder marker, the traversal path is limited
+to being the remainder segments of a request URL when a route matches.
+However, when you use the ``traverse`` argument or attribute, you have more
+control over how to compose a traversal path.
Here's a use of the ``traverse`` pattern in a call to
:meth:`~pyramid.config.Configurator.add_route`:
@@ -381,30 +366,27 @@ Here's a use of the ``traverse`` pattern in a call to
config.add_route('abc', '/articles/{article}/edit',
traverse='/{article}')
-The syntax of the ``traverse`` argument is the same as it is for
-``pattern``.
+The syntax of the ``traverse`` argument is the same as it is for ``pattern``.
-If, as above, the ``pattern`` provided is ``/articles/{article}/edit``,
-and the ``traverse`` argument provided is ``/{article}``, when a
-request comes in that causes the route to match in such a way that the
-``article`` match value is ``1`` (when the request URI is
-``/articles/1/edit``), the traversal path will be generated as ``/1``.
-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.
-The :ref:`traversal_chapter` chapter has more information about traversal.
+If, as above, the ``pattern`` provided is ``/articles/{article}/edit``, and the
+``traverse`` argument provided is ``/{article}``, when a request comes in that
+causes the route to match in such a way that the ``article`` match value is
+``1`` (when the request URI is ``/articles/1/edit``), the traversal path will
+be generated as ``/1``. 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. 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
-``traverse`` pattern should not contain segment markers that do not
-exist in the ``path``.
+If the traversal path contains segment marker names which are not present in
+the pattern argument, a runtime error will occur. The ``traverse`` pattern
+should not contain segment markers that do not exist in the ``path``.
-Note that the ``traverse`` argument is ignored when attached to a
-route that has a ``*traverse`` remainder marker in its pattern.
+Note that the ``traverse`` argument is ignored when attached to a route that
+has a ``*traverse`` remainder marker in its pattern.
-Traversal will begin at the root object implied by this route (either
-the global root, or the object returned by the ``factory`` associated
-with this route).
+Traversal will begin at the root object implied by this route (either the
+global root, or the object returned by the ``factory`` associated with this
+route).
.. index::
pair: hybrid applications; global views
@@ -412,14 +394,13 @@ with this route).
Making Global Views Match
+++++++++++++++++++++++++
-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"``
+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
@@ -445,10 +426,10 @@ traversal. For instance, the :func:`pyramid.wsgi.wsgiapp2` decorator and the
from the request's subpath when its ``use_subpath`` argument is ``True``, so
it's useful to be able to influence this value.
-When ``*subpath`` exists in a pattern, no path is actually traversed,
-but the traversal algorithm will return a :term:`subpath` list implied
-by the capture value of ``*subpath``. You'll see this pattern most
-commonly in route declarations that look like this:
+When ``*subpath`` exists in a pattern, no path is actually traversed, but the
+traversal algorithm will return a :term:`subpath` list implied by the capture
+value of ``*subpath``. You'll see this pattern most commonly in route
+declarations that look like this:
.. code-block:: python
:linenos:
@@ -460,98 +441,13 @@ commonly in route declarations that look like this:
config.add_route('static', '/static/*subpath')
config.add_view(www, route_name='static')
-``mypackage.views.www`` is an instance of
-:class:`pyramid.static.static_view`. This effectively tells the static
-helper to traverse everything in the subpath as a filename.
-
-.. index::
- pair: hybrid applications; corner cases
-
-Corner Cases
-------------
-
-A number of corner case "gotchas" exist when using a hybrid
-application. We'll detail them here.
-
-Registering a Default View for a Route That Has a ``view`` Attribute
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. warning:: As of :app:`Pyramid` 1.1 this section is slated to be removed in
- a later documentation release because the ability to add views
- directly to the :term:`route configuration` by passing a ``view`` argument
- to ``add_route`` has been deprecated.
-
-It is an error to provide *both* a ``view`` argument to a :term:`route
-configuration` *and* a :term:`view configuration` which names a
-``route_name`` that has no ``name`` value or the empty ``name`` value. For
-example, this pair of declarations will generate a conflict error at startup
-time.
-
-.. code-block:: python
- :linenos:
-
- config.add_route('home', '{foo}/{bar}/*traverse',
- view='myproject.views.home')
- config.add_view('myproject.views.another', route_name='home')
-
-This is because the ``view`` argument to the
-:meth:`~pyramid.config.Configurator.add_route` above is an *implicit*
-default view when that route matches. ``add_route`` calls don't *need* to
-supply a view attribute. For example, this ``add_route`` call:
-
-.. code-block:: python
- :linenos:
-
- config.add_route('home', '{foo}/{bar}/*traverse',
- view='myproject.views.home')
+``mypackage.views.www`` is an instance of :class:`pyramid.static.static_view`.
+This effectively tells the static helper to traverse everything in the subpath
+as a filename.
-Can also be spelled like so:
-
-.. code-block:: python
- :linenos:
-
- config.add_route('home', '{foo}/{bar}/*traverse')
- config.add_view('myproject.views.home', route_name='home')
-
-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 Pattern
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Here's another corner case that just makes no sense:
-
-.. code-block:: python
- :linenos:
-
- config.add_route('abc', '/abc', view='myproject.views.abc')
- config.add_view('myproject.views.bazbuz', name='bazbuz',
- route_name='abc')
-
-The above view declaration is useless, because it will never be matched when
-the route it references has matched. Only the view associated with the route
-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 useful, the special ``*traverse``
-token must end the route's pattern. For example:
-
-.. code-block:: python
- :linenos:
-
- config.add_route('abc', '/abc/*traverse', view='myproject.views.abc')
- 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.
.. index::
- pair: hybrid urls; generating
+ pair: hybrid URLs; generating
.. _generating_hybrid_urls:
@@ -560,16 +456,16 @@ Generating Hybrid URLs
.. versionadded:: 1.5
-The :meth:`pyramid.request.Request.resource_url` method and the
-:meth:`pyramid.request.Request.resource_path` method both accept optional
+The :meth:`pyramid.request.Request.resource_url` method and the
+:meth:`pyramid.request.Request.resource_path` method both accept optional
keyword arguments that make it easier to generate route-prefixed URLs that
-contain paths to traversal resources:``route_name``, ``route_kw``, and
+contain paths to traversal resources: ``route_name``, ``route_kw``, and
``route_remainder_name``.
Any route that has a pattern that contains a ``*remainder`` pattern (any
-stararg remainder pattern, such as ``*traverse`` or ``*subpath`` or ``*fred``)
-can be used as the target name for ``request.resource_url(..., route_name=)``
-and ``request.resource_path(..., route_name=)``.
+stararg remainder pattern, such as ``*traverse``, ``*subpath``, or ``*fred``)
+can be used as the target name for ``request.resource_url(..., route_name=)``
+and ``request.resource_path(..., route_name=)``.
For example, let's imagine you have a route defined in your Pyramid application
like so:
@@ -578,7 +474,7 @@ like so:
config.add_route('mysection', '/mysection*traverse')
-If you'd like to generate the URL ``http://example.com/mysection/a/``, you can
+If you'd like to generate the URL ``http://example.com/mysection/a/``, you can
use the following incantation, assuming that the variable ``a`` below points to
a resource that is a child of the root with a ``__name__`` of ``a``:
@@ -592,14 +488,14 @@ You can generate only the path portion ``/mysection/a/`` assuming the same:
request.resource_path(a, route_name='mysection')
-The path is virtual host aware, so if the ``X-Vhm-Root`` environ variable is
-present in the request, and it's set to ``/a``, the above call to
-``request.resource_url`` would generate ``http://example.com/mysection/``
-and the above call to ``request.resource_path`` would generate ``/mysection/``.
-See :ref:`virtual_root_support` for more information.
+The path is virtual host aware, so if the ``X-Vhm-Root`` environment variable
+is present in the request, and it's set to ``/a``, the above call to
+``request.resource_url`` would generate ``http://example.com/mysection/``, and
+the above call to ``request.resource_path`` would generate ``/mysection/``. See
+:ref:`virtual_root_support` for more information.
If the route you're trying to use needs simple dynamic part values to be filled
-in to succesfully generate the URL, you can pass these as the ``route_kw``
+in to succesfully generate the URL, you can pass these as the ``route_kw``
argument to ``resource_url`` and ``resource_path``. For example, assuming that
the route definition is like so:
@@ -613,15 +509,15 @@ You can pass ``route_kw`` in to fill in ``{id}`` above:
request.resource_url(a, route_name='mysection', route_kw={'id':'1'})
-If you pass ``route_kw`` but do not pass ``route_name``, ``route_kw`` will
-be ignored.
+If you pass ``route_kw`` but do not pass ``route_name``, ``route_kw`` will be
+ignored.
-By default this feature works by calling ``route_url`` under the hood,
-and passing the value of the resource path to that function as ``traverse``.
-If your route has a different ``*stararg`` remainder name (such as
-``*subpath``), you can tell ``resource_url`` or ``resource_path`` to use that
-instead of ``traverse`` by passing ``route_remainder_name``. For example,
-if you have the following route:
+By default this feature works by calling ``route_url`` under the hood, and
+passing the value of the resource path to that function as ``traverse``. If
+your route has a different ``*stararg`` remainder name (such as ``*subpath``),
+you can tell ``resource_url`` or ``resource_path`` to use that instead of
+``traverse`` by passing ``route_remainder_name``. For example, if you have the
+following route:
.. code-block:: python
@@ -631,10 +527,10 @@ You can fill in the ``*subpath`` value using ``resource_url`` by doing:
.. code-block:: python
- request.resource_path(a, route_name='mysection',
+ request.resource_path(a, route_name='mysection',
route_remainder_name='subpath')
-If you pass ``route_remainder_name`` but do not pass ``route_name``,
+If you pass ``route_remainder_name`` but do not pass ``route_name``,
``route_remainder_name`` will be ignored.
If you try to use ``resource_path`` or ``resource_url`` when the ``route_name``
@@ -642,12 +538,11 @@ argument points at a route that does not have a remainder stararg, an error
will not be raised, but the generated URL will not contain any remainder
information either.
-All other values that are normally passable to ``resource_path`` and
-``resource_url`` (such as ``query``, ``anchor``, ``host``, ``port``, and
+All other values that are normally passable to ``resource_path`` and
+``resource_url`` (such as ``query``, ``anchor``, ``host``, ``port``, and
positional elements) work as you might expect in this configuration.
Note that this feature is incompatible with the ``__resource_url__`` feature
(see :ref:`overriding_resource_url_generation`) implemented on resource
objects. Any ``__resource_url__`` supplied by your resource will be ignored
when you pass ``route_name``.
-