From 450006eb2493833ddfd3a0f623c3295f1e8a0e47 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 19 Dec 2010 12:45:30 -0500 Subject: wording --- docs/narr/traversal.rst | 281 +++++++++++++++++++++++------------------------- 1 file changed, 137 insertions(+), 144 deletions(-) diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst index 7b9c76581..48e90e4d9 100644 --- a/docs/narr/traversal.rst +++ b/docs/narr/traversal.rst @@ -3,10 +3,12 @@ Traversal ========= -:term:`Traversal` is a :term:`resource location` mechanism. It is the act of -finding a :term:`context` resource by walking over a :term:`resource tree`, -starting from a :term:`root` resource, using a :term:`request` object as a -source of path information. +:term:`Traversal` It provides an alternative to using :term:`URL dispatch` to +map a URL to a :term:`view callable`. It is a :term:`resource location` +mechanism. It is the act of finding a :term:`context` resource by walking +over a :term:`resource tree`, starting from a :term:`root` resource, using a +:term:`request` object as a source of path information. Once a context +resource is found, a view callable is looked up and invoked. In this chapter, we'll provide a high-level overview of traversal, we'll explain the concept of a resource tree, and we'll show how traversal might be @@ -25,7 +27,7 @@ of the URL into a set of nested dictionary-like objects called the directories in a file system. Traversal walks down the path until it finds a published "directory" or "file". The resource we find as the result of a traversal becomes the :term:`context`. A separate :term:`view lookup` -subsystem is used to then find some code willing "publish" the context +subsystem is used to then find some view code willing "publish" the context resource. .. index:: @@ -47,31 +49,30 @@ segments. For example, the ``PATH_INFO`` string ``/a/b/c`` is converted to the sequence ``['a', 'b', 'c']``. After the path info is converted, a lookup is performed against the resource -tree for each path segment. Each lookup uses the ``__getitem__`` method of -a resource in the tree. +tree for each path segment. Each lookup uses the ``__getitem__`` method of a +resource in the tree. For example, if the path info sequence is ``['a', 'b', 'c']``: -- :term:`Traversal` pops the first element (``a``) from the path - segment sequence and attempts to call the root resource's - ``__getitem__`` method using that value (``a``) as an argument; - we'll presume it succeeds. +- :term:`Traversal` pops the first element (``a``) from the path segment + sequence and attempts to call the root resource's ``__getitem__`` method + using that value (``a``) as an argument; we'll presume it succeeds. - When the root resource's ``__getitem__`` succeeds it will return another resource, which we'll call "A". The :term:`context` temporarily becomes the "A" resource. -- The next segment (``b``) is popped from the path sequence, and the - "A" resource's ``__getitem__`` is called with that value (``b``) as an +- The next segment (``b``) is popped from the path sequence, and the "A" + resource's ``__getitem__`` is called with that value (``b``) as an argument; we'll presume it succeeds. - When the "A" resource's ``__getitem__`` succeeds it will return another - resource, which we'll call "B". The :term:`context` temporarily - becomes the "B" resource. + resource, which we'll call "B". The :term:`context` temporarily becomes + the "B" resource. -This process continues until the path segment sequence is exhausted or a -lookup for a path element fails. In either case, a :term:`context` resouce -is found. +This process continues until the path segment sequence is exhausted or a path +element cannot be resolved to a resource. In either case, a :term:`context` +resource is chosen. Traversal "stops" when it either reaches a leaf level resource in your resource tree or when the path segments implied by the URL "run out". The @@ -81,10 +82,10 @@ point during traversal any resource in the tree doesn't have a a :exc:`KeyError`, traversal ends immediately, and that resource becomes the :term:`context`. -The results of a :term:`traversal` also include a :term:`view name`. -The :term:`view name` is the *first* URL path segment in the set of -``PATH_INFO`` segments "left over" in the path segment list popped by -the traversal process *after* traversal finds a context resource. +The results of a :term:`traversal` also include a :term:`view name`. The +:term:`view name` is the *first* URL path segment in the set of ``PATH_INFO`` +segments "left over" in the path segment list popped by the traversal process +*after* traversal finds a context resource. The combination of the context resource and the :term:`view name` found via traversal is used later in the same request by a separate :app:`Pyramid` @@ -102,10 +103,11 @@ lookup is explained within the :ref:`views_chapter` chapter. The Resource Tree ----------------- -When your application uses :term:`traversal` to resolve URLs to code, your +When your application uses :term:`traversal` to resolve URLs to code, the application must supply a :term:`resource tree` to :app:`Pyramid`. The resource tree is a set of nested dictionary-like objects. The root of the -tree is represented by a :term:`root` resource. +tree is represented by a :term:`root` resource. The tree is effectively a +nested set of dictionary-like objects. In order to supply a root resource for an application, at system startup time, the :app:`Pyramid` :term:`Router` is configured with a callback known @@ -138,7 +140,7 @@ alternately be passed to the ``Configurator`` as a :term:`dotted Python name` which refers to a root factory defined in a different module. A root factory is passed a :term:`request` object and it is expected to -return a resource which represents the root of the resource tree. All +return an object which represents the root of the resource tree. All :term:`traversal` will begin at this root resource. Usually a root factory for a traversal-based application will be more complicated than the above ``Root`` class; in particular it may be associated with a database connection @@ -151,9 +153,9 @@ always returns a resource that has no child resources. .. sidebar:: Emulating the Default Root Factory - For purposes of understanding the default root factory better, - we'll note that you can emulate the default root factory by using - this code as an explicit root factory in your application setup: + For purposes of understanding the default root factory better, we'll note + that you can emulate the default root factory by using this code as an + explicit root factory in your application setup: .. code-block:: python :linenos: @@ -190,12 +192,11 @@ whether an object is "containerish" or not (dictionary objects are Each container resource is presumed to be willing to return a child resource or raise a ``KeyError`` based on a name passed to its ``__getitem__``. -Leaf-level instances must not have a ``__getitem__``. If -instances that you'd like to be leaves already happen to have a -``__getitem__`` through some historical inequity, you should subclass -these resource types and cause their ``__getitem__`` methods to simply -raise a ``KeyError``. Or just disuse them and think up another -strategy. +Leaf-level instances must not have a ``__getitem__``. If instances that +you'd like to be leaves already happen to have a ``__getitem__`` through some +historical inequity, you should subclass these resource types and cause their +``__getitem__`` methods to simply raise a ``KeyError``. Or just disuse them +and think up another strategy. Usually, the traversal root is a *container* resource, and as such it contains other resources. However, it doesn't *need* to be a container. @@ -218,19 +219,17 @@ resource. This happens *ad infinitum* until all path segments are exhausted. The Traversal Algorithm ----------------------- -This section will attempt to explain the :app:`Pyramid` traversal -algorithm. We'll provide a description of the algorithm, a diagram of -how the algorithm works, and some example traversal scenarios that -might help you understand how the algorithm operates against a -specific resource tree. - -We'll also talk a bit about :term:`view lookup`. The -:ref:`views_chapter` chapter discusses :term:`view lookup` in detail, -and it is the canonical source for information about views. -Technically, :term:`view lookup` is a :app:`Pyramid` subsystem that -is separated from traversal entirely. However, we'll describe the -fundamental behavior of view lookup in the examples in the next few -sections to give you an idea of how traversal and view lookup +This section will attempt to explain the :app:`Pyramid` traversal algorithm. +We'll provide a description of the algorithm, a diagram of how the algorithm +works, and some example traversal scenarios that might help you understand +how the algorithm operates against a specific resource tree. + +We'll also talk a bit about :term:`view lookup`. The :ref:`views_chapter` +chapter discusses :term:`view lookup` in detail, and it is the canonical +source for information about views. Technically, :term:`view lookup` is a +:app:`Pyramid` subsystem that is separated from traversal entirely. However, +we'll describe the fundamental behavior of view lookup in the examples in the +next few sections to give you an idea of how traversal and view lookup cooperate, because they are almost always used together. .. index:: @@ -243,25 +242,24 @@ cooperate, because they are almost always used together. A Description of The Traversal Algorithm ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a user requests a page from your :mod:`traversal` -powered -application, the system uses this algorithm to find a :term:`context` -and a :term:`view name`. +When a user requests a page from your :mod:`traversal` -powered application, +the system uses this algorithm to find a :term:`context` resource and a +:term:`view name`. #. The request for the page is presented to the :app:`Pyramid` - :term:`router` in terms of a standard :term:`WSGI` request, which - is represented by a WSGI environment and a WSGI ``start_response`` - callable. + :term:`router` in terms of a standard :term:`WSGI` request, which is + represented by a WSGI environment and a WSGI ``start_response`` callable. #. The router creates a :term:`request` object based on the WSGI environment. -#. The :term:`root factory` is called with the :term:`request`. It - returns a :term:`root` resource. +#. The :term:`root factory` is called with the :term:`request`. It returns + a :term:`root` resource. -#. The router uses the WSGI environment's ``PATH_INFO`` information - to determine the path segments to traverse. The leading slash is - stripped off ``PATH_INFO``, and the remaining path segments are - split on the slash character to form a traversal sequence. +#. The router uses the WSGI environment's ``PATH_INFO`` information to + determine the path segments to traverse. The leading slash is stripped + off ``PATH_INFO``, and the remaining path segments are split on the slash + character to form a traversal sequence. The traversal algorithm by default attempts to first URL-unquote and then Unicode-decode each path segment derived from ``PATH_INFO`` from its @@ -273,18 +271,18 @@ and a :term:`view name`. segment will be fully URL-unquoted and UTF8-decoded before it is passed it to the ``__getitem__`` of any resource during traversal. - Thus, a request with a ``PATH_INFO`` variable of ``/a/b/c`` maps - to the traversal sequence ``[u'a', u'b', u'c']``. + Thus, a request with a ``PATH_INFO`` variable of ``/a/b/c`` maps to the + traversal sequence ``[u'a', u'b', u'c']``. #. :term:`Traversal` begins at the root resource returned by the root factory. For the traversal sequence ``[u'a', u'b', u'c']``, the root resource's ``__getitem__`` is called with the name ``a``. Traversal continues through the sequence. In our example, if the root resource's ``__getitem__`` called with the name ``a`` returns a resource (aka - "resource ``a``"), that resource's ``__getitem__`` is called with the name - ``b``. If resource A returns a resource when asked for ``b``, "resource - ``b``"'s ``__getitem__`` is then asked for the name ``c``, and may return - "resource ``c``". + "resource ``a``"), that resource's ``__getitem__`` is called with the + name ``b``. If resource A returns a resource when asked for ``b``, + "resource ``b``"'s ``__getitem__`` is then asked for the name ``c``, and + may return "resource ``c``". #. Traversal ends when a) the entire path is exhausted or b) when any resouce raises a :exc:`KeyError` from its ``__getitem__`` or c) when any @@ -293,33 +291,31 @@ and a :term:`view name`. with the set of characters ``@@`` (indicating that the characters following the ``@@`` token should be treated as a :term:`view name`). -#. When traversal ends for any of the reasons in the previous step, - the last resource found during traversal is deemed to be the - :term:`context`. If the path has been exhausted when traversal - ends, the :term:`view name` is deemed to be the empty string - (``''``). However, if the path was *not* exhausted before - traversal terminated, the first remaining path segment is treated - as the view name. - -#. Any subsequent path elements after the :term:`view name` is found - are deemed the :term:`subpath`. The subpath is always a sequence - of path segments that come from ``PATH_INFO`` that are "left over" - after traversal has completed. - -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 -invokes :term:`view lookup` with the context and view name -information. +#. When traversal ends for any of the reasons in the previous step, the last + resource found during traversal is deemed to be the :term:`context`. If + the path has been exhausted when traversal ends, the :term:`view name` is + deemed to be the empty string (``''``). However, if the path was *not* + exhausted before traversal terminated, the first remaining path segment + is treated as the view name. + +#. Any subsequent path elements after the :term:`view name` is found are + deemed the :term:`subpath`. The subpath is always a sequence of path + segments that come from ``PATH_INFO`` that are "left over" after + traversal has completed. + +Once the :term:`context` resource, the :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 invokes +:term:`view lookup` with the context and view name information. The traversal algorithm exposes two special cases: -- You will often end up with a :term:`view name` that is the empty - string as the result of a particular traversal. This indicates that - the view lookup machinery should look up the :term:`default view`. - The default view is a view that is registered with no name or a view - which is registered with a name that equals the empty string. +- You will often end up with a :term:`view name` that is the empty string as + the result of a particular traversal. This indicates that the view lookup + machinery should look up the :term:`default view`. The default view is a + view that is registered with no name or a view which is registered with a + name that equals the empty string. - If any path segment element begins with the special characters ``@@`` (think of them as goggles), the value of that segment minus the goggle @@ -327,10 +323,10 @@ The traversal algorithm exposes two special cases: stops there. This allows you to address views that may have the same names as resource names in the tree unambiguously. -Finally, traversal is responsible for locating a :term:`virtual root`. -A virtual root is used during "virtual hosting"; see the -:ref:`vhosting_chapter` chapter for information. We won't speak more -about it in this chapter. +Finally, traversal is responsible for locating a :term:`virtual root`. A +virtual root is used during "virtual hosting"; see the +:ref:`vhosting_chapter` chapter for information. We won't speak more about +it in this chapter. .. image:: resourcetreetraverser.png @@ -340,15 +336,14 @@ about it in this chapter. Traversal Algorithm Examples ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -No one can be expected to understand the traversal algorithm by -analogy and description alone, so let's examine some traversal -scenarios that use concrete URLs and resource tree compositions. +No one can be expected to understand the traversal algorithm by analogy and +description alone, so let's examine some traversal scenarios that use +concrete URLs and resource tree compositions. Let's pretend the user asks for -``http://example.com/foo/bar/baz/biz/buz.txt``. The request's -``PATH_INFO`` in that case is ``/foo/bar/baz/biz/buz.txt``. Let's -further pretend that when this request comes in that we're traversing -the following resource tree: +``http://example.com/foo/bar/baz/biz/buz.txt``. The request's ``PATH_INFO`` +in that case is ``/foo/bar/baz/biz/buz.txt``. Let's further pretend that +when this request comes in that we're traversing the following resource tree: .. code-block:: text @@ -360,20 +355,21 @@ the following resource tree: Here's what happens: -- :mod:`traversal` traverses the root, and attempts to find "foo", - which it finds. +- :mod:`traversal` traverses the root, and attempts to find "foo", which it + finds. -- :mod:`traversal` traverses "foo", and attempts to find "bar", which - it finds. +- :mod:`traversal` traverses "foo", and attempts to find "bar", which it + finds. -- :mod:`traversal` traverses bar, and attempts to find "baz", which it - does not find ("bar" raises a :exc:`KeyError` when asked for "baz"). +- :mod:`traversal` traverses bar, and attempts to find "baz", which it does + not find (the "bar" resource raises a :exc:`KeyError` when asked for + "baz"). -The fact that it does not find "baz" at this point does not signify an -error condition. It signifies that: +The fact that it does not find "baz" at this point does not signify an error +condition. It signifies that: -- the :term:`context` is "bar" (the context is the last resource found - during traversal). +- the :term:`context` is the "bar" resource (the context is the last resource + found during traversal). - the :term:`view name` is ``baz`` @@ -387,13 +383,12 @@ to find out what "type" it is. Let's say it finds that the context is a Using the :term:`view name` (``baz``) and the type, view lookup asks the :term:`application registry` this question: -- Please find me a :term:`view callable` registered using a - :term:`view configuration` with the name "baz" that can be used for - the class ``Bar``. +- Please find me a :term:`view callable` registered using a :term:`view + configuration` with the name "baz" that can be used for the class ``Bar``. Let's say that view lookup finds no matching view type. In this -circumstance, the :app:`Pyramid` :term:`router` returns the result -of the :term:`not found view` and the request ends. +circumstance, the :app:`Pyramid` :term:`router` returns the result of the +:term:`not found view` and the request ends. However, for this tree: @@ -411,23 +406,23 @@ However, for this tree: The user asks for ``http://example.com/foo/bar/baz/biz/buz.txt`` -- :mod:`traversal` traverses "foo", and attempts to find "bar", which - it finds. +- :mod:`traversal` traverses "foo", and attempts to find "bar", which it + finds. -- :mod:`traversal` traverses "bar", and attempts to find "baz", which - it finds. +- :mod:`traversal` traverses "bar", and attempts to find "baz", which it + finds. -- :mod:`traversal` traverses "baz", and attempts to find "biz", which - it finds. +- :mod:`traversal` traverses "baz", and attempts to find "biz", which it + finds. -- :mod:`traversal` traverses "biz", and attempts to find "buz.txt" - which it does not find. +- :mod:`traversal` traverses "biz", and attempts to find "buz.txt" which it + does not find. -The fact that it does not find "buz.txt" at this point does not -signify an error condition. It signifies that: +The fact that it does not find a resource related to "buz.txt" at this point +does not signify an error condition. It signifies that: -- the :term:`context` is "biz" (the context is the last resource found - during traversal). +- the :term:`context` is the "biz" resource (the context is the last resource + found during traversal). - the :term:`view name` is "buz.txt" @@ -435,21 +430,20 @@ signify an error condition. It signifies that: At this point, traversal has ended, and :term:`view lookup` begins. -Because it's the "context" resource, the view lookup machinery examines "biz" -to find out what "type" it is. Let's say it finds that the context is a -``Biz`` type (because "biz" is an instance of the Python class ``Biz``). -Using the :term:`view name` (``buz.txt``) and the type, view lookup asks the -:term:`application registry` this question: +Because it's the "context" resource, the view lookup machinery examines the +"biz" resource to find out what "type" it is. Let's say it finds that the +resource is a ``Biz`` type (because "biz" is an instance of the Python class +``Biz``). Using the :term:`view name` (``buz.txt``) and the type, view +lookup asks the :term:`application registry` this question: - Please find me a :term:`view callable` registered with a :term:`view configuration` with the name ``buz.txt`` that can be used for class ``Biz``. -Let's say that question is answered by the application registry; in -such a situation, the application registry returns a :term:`view -callable`. The view callable is then called with the current -:term:`WebOb` :term:`request` as the sole argument: ``request``; it is -expected to return a response. +Let's say that question is answered by the application registry; in such a +situation, the application registry returns a :term:`view callable`. The +view callable is then called with the current :term:`WebOb` :term:`request` +as the sole argument: ``request``; it is expected to return a response. .. sidebar:: The Example View Callables Accept Only a Request; How Do I Access the Context Resource? @@ -471,16 +465,15 @@ expected to return a response. References ---------- -A tutorial showing how :term:`traversal` can be used within a -:app:`Pyramid` application exists in :ref:`bfg_wiki_tutorial`. +A tutorial showing how :term:`traversal` can be used within a :app:`Pyramid` +application exists in :ref:`bfg_wiki_tutorial`. See the :ref:`views_chapter` chapter for detailed information about :term:`view lookup`. -The :mod:`pyramid.traversal` module contains API functions that -deal with traversal, such as traversal invocation from within -application code. +The :mod:`pyramid.traversal` module contains API functions that deal with +traversal, such as traversal invocation from within application code. -The :func:`pyramid.url.resource_url` function generates a URL when -given a resource retrieved from a resource tree. +The :func:`pyramid.url.resource_url` function generates a URL when given a +resource retrieved from a resource tree. -- cgit v1.2.3