summaryrefslogtreecommitdiff
path: root/docs/narr/traversal.rst
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2010-12-19 04:18:12 -0500
committerChris McDonough <chrism@plope.com>2010-12-19 04:18:12 -0500
commit780999e8504d1087d4e48a822174ebb69309bcfe (patch)
tree4eb9eb08b3db003b632ee69d47dfb2b3b45c0f17 /docs/narr/traversal.rst
parentd9fccbbd2e8c1122aba34c854fa08ca2c659642d (diff)
downloadpyramid-780999e8504d1087d4e48a822174ebb69309bcfe.tar.gz
pyramid-780999e8504d1087d4e48a822174ebb69309bcfe.tar.bz2
pyramid-780999e8504d1087d4e48a822174ebb69309bcfe.zip
context finding -> resource location
Diffstat (limited to 'docs/narr/traversal.rst')
-rw-r--r--docs/narr/traversal.rst221
1 files changed, 107 insertions, 114 deletions
diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst
index 9bc6014cd..98a009341 100644
--- a/docs/narr/traversal.rst
+++ b/docs/narr/traversal.rst
@@ -3,10 +3,10 @@
Traversal
=========
-:term:`Traversal` is a :term:`context finding` mechanism. It is the act of
-finding a :term:`context` and a :term:`view name` 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` 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.
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
@@ -58,22 +58,21 @@ The contents of ``myfile`` are now printed on the user's behalf.
:app:`Pyramid` is very much like this inexperienced UNIX user as it uses
:term:`traversal` against a resource tree. In this analogy, we can map the
``cat`` program to the :app:`Pyramid` concept of a :term:`view callable`: it
-is a program that can be run against some :term:`context` as the result of
-:term:`view lookup`. The file being operated on in this analogy is the
-:term:`context` object; the context is the "last resource found" in a
-traversal. The directory structure is the resource tree being traversed.
-The act of progressively changing directories to find the file as well as the
-handling of a ``cd`` error as a stop condition is analogous to
+is a program that can be run against some :term:`resource` (the "context") as
+the result of :term:`view lookup`. The file being operated on in this
+analogy is the :term:`context` resource; the context is the "last resource
+found" in a traversal. The directory structure is the resource tree being
+traversed. The act of progressively changing directories to find the file as
+well as the handling of a ``cd`` error as a stop condition is analogous to
:term:`traversal`.
-The analogy we've used is not *exactly* correct, because, while the
-naive user already knows which command he wants to invoke before he
-starts "traversing" (``cat``), :app:`Pyramid` needs to obtain that
-information from the path being traversed itself. In
-:term:`traversal`, the "command" meant to be invoked is a :term:`view
-callable`. A view callable is derived via :term:`view lookup` from
-the combination of the :term:`view name` and the :term:`context`.
-Traversal is the act of obtaining these two items.
+The analogy we've used is not *exactly* correct, because, while the naive
+user already knows which command he wants to invoke before he starts
+"traversing" (``cat``), :app:`Pyramid` needs to obtain that information from
+the path being traversed itself. In :term:`traversal`, the "command" meant
+to be invoked is a :term:`view callable`. A view callable is derived via
+:term:`view lookup` from the combination of the :term:`request` and the
+:term:`context`.
.. index::
single: traversal overview
@@ -81,49 +80,48 @@ Traversal is the act of obtaining these two items.
A High-Level Overview of Traversal
----------------------------------
-:term:`Traversal` is dependent on information in a :term:`request`
-object. Every :term:`request` object contains URL path information in
-the ``PATH_INFO`` portion of the :term:`WSGI` environment. The
-``PATH_INFO`` portion of the WSGI environment is the portion of a
-request's URL following the hostname and port number, but before any
-query string elements or fragment element. For example the
-``PATH_INFO`` portion of the URL
+:term:`Traversal` is dependent on information in a :term:`request` object.
+Every :term:`request` object contains URL path information in the
+``PATH_INFO`` portion of the :term:`WSGI` environment. The ``PATH_INFO``
+portion of the WSGI environment is the portion of a request's URL following
+the hostname and port number, but before any query string elements or
+fragment element. For example the ``PATH_INFO`` portion of the URL
``http://example.com:8080/a/b/c?foo=1`` is ``/a/b/c``.
-Traversal treats the ``PATH_INFO`` segment of a URL as a sequence of
-path segments. For example, the ``PATH_INFO`` string ``/a/b/c`` is
-converted to the sequence ``['a', 'b', 'c']``.
+Traversal treats the ``PATH_INFO`` segment of a URL as a sequence of path
+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
-an object in the tree.
+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 object's
+ 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 object's ``__getitem__`` succeeds it will return an
- object, which we'll call "A". The :term:`context` temporarily
- becomes the "A" object.
+- 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" object's ``__getitem__`` is called with that value (``b``) as an
+ "A" resource's ``__getitem__`` is called with that value (``b``) as an
argument; we'll presume it succeeds.
-- When the "A" object's ``__getitem__`` succeeds it will return an
- object, which we'll call "B". The :term:`context` temporarily
- becomes the "B" object.
+- 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.
-This process continues until the path segment sequence is exhausted or
-a lookup for a path element fails. In either case, a :term:`context`
+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.
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
-object that traversal "stops on" becomes the :term:`context`. If at any
+resource that traversal "stops on" becomes the :term:`context`. If at any
point during traversal any resource in the tree doesn't have a
``__getitem__`` method, or if the ``__getitem__`` method of a resource raises
a :exc:`KeyError`, traversal ends immediately, and that resource becomes the
@@ -132,14 +130,13 @@ a :exc:`KeyError`, traversal ends immediately, and that resource becomes the
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 object.
+the traversal process *after* traversal finds a context resource.
-The combination of the :term:`context` object and the :term:`view
-name` found via traversal is used later in the same request by a
-separate :app:`Pyramid` subsystem -- the :term:`view lookup`
-subsystem -- to find a :term:`view callable` later within the same
-request. How :app:`Pyramid` performs view lookup is explained
-within the :ref:`views_chapter` chapter.
+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`
+subsystem -- the :term:`view lookup` subsystem -- to find a :term:`view
+callable` later within the same request. How :app:`Pyramid` performs view
+lookup is explained within the :ref:`views_chapter` chapter.
.. index::
single: object tree
@@ -153,9 +150,9 @@ The Resource Tree
When your application uses :term:`traversal` to resolve URLs to code, your
application must supply the a resource tree to :app:`Pyramid`. This tree is
-represented by a :term:`root` object.
+represented by a :term:`root` resource.
-In order to supply a root object for an application, at system startup
+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 as a :term:`root factory`. The root factory is
supplied by the application developer as the ``root_factory`` argument
@@ -179,27 +176,24 @@ named ``config``:
config = Configurator(root_factory=Root)
-Using the ``root_factory`` argument to a
-:class:`pyramid.config.Configurator` constructor tells your
-:app:`Pyramid` application to call this root factory to generate a
-root object whenever a request enters the application. This root
-factory is also known as the global root factory. A root factory can
-alternately be passed to the ``Configurator`` as a :term:`dotted
-Python name` which refers to a root factory object defined in a
-different module.
+Using the ``root_factory`` argument to a :class:`pyramid.config.Configurator`
+constructor tells your :app:`Pyramid` application to call this root factory
+to generate a root resource whenever a request enters the application. This
+root factory is also known as the global root factory. A root factory can
+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 an object which represents the root of the resource tree. All
-:term:`traversal` will begin at this root object. Usually a root factory for
-a traversal-based application will be more complicated than the above
-``Root`` object; in particular it may be associated with a database
-connection or another persistence mechanism. A root object is often an
-instance of a class which has a ``__getitem__`` method.
+return a resource 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 or another persistence mechanism.
If no :term:`root factory` is passed to the :app:`Pyramid`
:term:`Configurator` constructor, or the ``root_factory`` is specified
as the value ``None``, a *default* root factory is used. The default
-root factory always returns an object that has no child resources.
+root factory always returns a resource that has no child resources.
.. sidebar:: Emulating the Default Root Factory
@@ -218,8 +212,8 @@ root factory always returns an object that has no child resources.
The default root factory is just a really stupid object that has no
behavior or state. Using :term:`traversal` against an application that
- uses the resource tree supplied by the default root object is not very
- interesting, because the default root object has no children. Its
+ uses the resource tree supplied by the default root resource is not very
+ interesting, because the default root resource has no children. Its
availability is more useful when you're developing an application using
:term:`URL dispatch`.
@@ -235,7 +229,7 @@ There is only one difference between a *container* resource and a *leaf*
resource: *container* resources possess a ``__getitem__`` method while *leaf*
resources do not. The ``__getitem__`` method was chosen as the signifying
difference between the two types of resources because the presence of this
-method is how Python itself typically determines whether an object is
+method is how Python itself typically determines whether a resource is
"containerish" or not.
Each container resource is presumed to be willing to return a child resource
@@ -252,13 +246,13 @@ Usually, the traversal root is a *container* resource, and as such it
contains other resources. However, it doesn't *need* to be a container.
Your resource tree can be as shallow or as deep as you require.
-In general, the resource tree is traversed beginning at its root object using
-a sequence of path elements described by the ``PATH_INFO`` of the current
-request; if there are path segments, the root object's ``__getitem__`` is
-called with the next path segment, and it is expected to return another
-resource object. The resulting object's ``__getitem__`` is called with the
-very next path segment, and it is expected to return another resource object.
-This happens *ad infinitum* until all path segments are exhausted.
+In general, the resource tree is traversed beginning at its root resource
+using a sequence of path elements described by the ``PATH_INFO`` of the
+current request; if there are path segments, the root resource's
+``__getitem__`` is called with the next path segment, and it is expected to
+return another resource. The resulting resource's ``__getitem__`` is called
+with the very next path segment, and it is expected to return another
+resource. This happens *ad infinitum* until all path segments are exhausted.
.. index::
single: traversal algorithm
@@ -307,7 +301,7 @@ and a :term:`view name`.
environment.
#. The :term:`root factory` is called with the :term:`request`. It
- returns a :term:`root` object.
+ 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
@@ -327,15 +321,15 @@ and a :term:`view name`.
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 object returned by the root
- factory. For the traversal sequence ``[u'a', u'b', u'c']``, the
- root object's ``__getitem__`` is called with the name ``a``.
- Traversal continues through the sequence. In our example, if the
- root object's ``__getitem__`` called with the name ``a`` returns
- an object (aka "object ``a``"), that object's ``__getitem__`` is
- called with the name ``b``. If object A returns an object when
- asked for ``b``, "object ``b``"'s ``__getitem__`` is then asked
- for the name ``c``, and may return "object ``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``".
#. 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
@@ -345,7 +339,7 @@ and a :term:`view name`.
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 object found during traversal is deemed to be the
+ 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
@@ -423,7 +417,7 @@ Here's what happens:
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 item found
+- the :term:`context` is "bar" (the context is the last resource found
during traversal).
- the :term:`view name` is ``baz``
@@ -432,11 +426,11 @@ error condition. It signifies that:
At this point, traversal has ended, and :term:`view lookup` begins.
-Because it's the "context", the view lookup machinery examines "bar"
-to find out what "type" it is. Let's say it finds that the context is
-a ``Bar`` type (because "bar" happens to be an instance of the class
-``Bar``). Using the :term:`view name` (``baz``) and the type, view
-lookup asks the :term:`application registry` this question:
+Because it's the "context" resource, the view lookup machinery examines "bar"
+to find out what "type" it is. Let's say it finds that the context is a
+``Bar`` type (because "bar" happens to be an instance of the class ``Bar``).
+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
@@ -477,7 +471,7 @@ The user asks for ``http://example.com/foo/bar/baz/biz/buz.txt``
The fact that it does not find "buz.txt" at this point does not
signify an error condition. It signifies that:
-- the :term:`context` is "biz" (the context is the last item found
+- the :term:`context` is "biz" (the context is the last resource found
during traversal).
- the :term:`view name` is "buz.txt"
@@ -486,11 +480,11 @@ signify an error condition. It signifies that:
At this point, traversal has ended, and :term:`view lookup` begins.
-Because it's the "context", 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 "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:
- Please find me a :term:`view callable` registered with a :term:`view
configuration` with the name ``buz.txt`` that can be used for class
@@ -502,22 +496,21 @@ 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?
-
- Most of the examples in this book assume that a view callable is
- typically passed only a :term:`request` object. Sometimes your
- view callables need access to the :term:`context`, especially when
- you use :term:`traversal`. You might use a supported alternate
- view callable argument list in your view callables such as the
- ``(context, request)`` calling convention described in
- :ref:`request_and_context_view_definitions`. But you don't need to
- if you don't want to. In view callables that accept only a
- request, the :term:`context` found by traversal is available as the
- ``context`` attribute of the request object,
- e.g. ``request.context``. The :term:`view name` is available as
- the ``view_name`` attribute of the request object,
- e.g. ``request.view_name``. Other :app:`Pyramid` -specific
- request attributes are also available as described in
+.. sidebar:: The Example View Callables Accept Only a Request; How Do I Access the Context Resource?
+
+ Most of the examples in this book assume that a view callable is typically
+ passed only a :term:`request` object. Sometimes your view callables need
+ access to the :term:`context` resource, especially when you use
+ :term:`traversal`. You might use a supported alternate view callable
+ argument list in your view callables such as the ``(context, request)``
+ calling convention described in
+ :ref:`request_and_context_view_definitions`. But you don't need to if you
+ don't want to. In view callables that accept only a request, the
+ :term:`context` resource found by traversal is available as the
+ ``context`` attribute of the request object, e.g. ``request.context``.
+ The :term:`view name` is available as the ``view_name`` attribute of the
+ request object, e.g. ``request.view_name``. Other :app:`Pyramid`
+ -specific request attributes are also available as described in
:ref:`special_request_attributes`.
References
@@ -534,5 +527,5 @@ deal with traversal, such as traversal invocation from within
application code.
The :func:`pyramid.url.resource_url` function generates a URL when
-given an object retrieved from an resource tree.
+given a resource retrieved from an resource tree.