diff options
Diffstat (limited to 'docs/narr/hybrid.rst')
| -rw-r--r-- | docs/narr/hybrid.rst | 72 |
1 files changed, 41 insertions, 31 deletions
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. |
