diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-07-03 01:41:04 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-07-03 01:41:04 +0000 |
| commit | 7bc20e11b5ed7314e5aaed000242d4d5950fc775 (patch) | |
| tree | 6cb253ea95617ca4f24aa365f145ec2f81bf53fc /docs/narr/traversal.rst | |
| parent | c43c358c7ec7d352fd4792b993e4609cbab37dba (diff) | |
| download | pyramid-7bc20e11b5ed7314e5aaed000242d4d5950fc775.tar.gz pyramid-7bc20e11b5ed7314e5aaed000242d4d5950fc775.tar.bz2 pyramid-7bc20e11b5ed7314e5aaed000242d4d5950fc775.zip | |
General editing walkthrough.
Diffstat (limited to 'docs/narr/traversal.rst')
| -rw-r--r-- | docs/narr/traversal.rst | 111 |
1 files changed, 61 insertions, 50 deletions
diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst index cfc484cf0..8e21150c1 100644 --- a/docs/narr/traversal.rst +++ b/docs/narr/traversal.rst @@ -3,12 +3,13 @@ Traversal ========= -When :term:`traversal` is used, the :mod:`repoze.bfg` *Router* parses -the URL associated with the request and splits the URL into path -segments. Based on these path segments, :mod:`repoze.bfg` traverses a -*model graph* in order to find a :term:`context`. It then attempts to -find a :term:`view` based on the *type* of the context (specified by -its Python class type or any :term:`interface` attached to it). If +When :term:`traversal` is used within a :mod:`repoze.bfg` application, +the :mod:`repoze.bfg` *Router* parses the URL associated with the +request. It splits the URL into individual path segments. Based on +these path segments, :mod:`repoze.bfg` traverses a *model graph* in +order to find a :term:`context`. It then attempts to find a +:term:`view` based on the *type* of the context (specified by its +Python class type or any :term:`interface` attached to it). If :mod:`repoze.bfg` finds a :term:`view` for the context, it calls it and returns a response to the user. @@ -81,8 +82,8 @@ application, the system uses this algorithm to determine which Python code to execute: #. The request for the page is presented to the :mod:`repoze.bfg` - "router" in terms of a standard :term:`WSGI` request, which is - represented by a WSGI environment and a ``start_response`` + :term:`router` in terms of a standard :term:`WSGI` request, which + is represented by a WSGI environment and a ``start_response`` callable. #. The router creates a :term:`WebOb` request object based on the @@ -145,15 +146,16 @@ code to execute: request, an :term:`authorization policy` is consulted to see if the "current user" (al determined by the the authentication policy) can perform the action. If he can, processing continues. - If he cannot, an ``HTTPUnauthorized`` error is raised. + If he cannot, the ``forbidden`` view is called (see + :ref:`changing_the_forbidden_view`). #. Armed with the context, the view name, and the subpath, the router performs a view lookup. It attemtps to look up a view from the :mod:`repoze.bfg` :term:`application registry` using the view name and the context. If a view function is found, it is called with the context and the request. It returns a response, which is fed - back upstream. If a view is not found, a generic WSGI - ``NotFound`` application is constructed and returned. + back upstream. If a view is not found, the ``notfound`` view is + called (see :ref:`changing_the_notfound_view`). In either case, the result is returned upstream via the :term:`WSGI` protocol. @@ -167,10 +169,10 @@ It's useful to be able to debug ``NotFound`` errors when they occur unexpectedly due to an application registry misconfiguration. To debug these errors, use the ``BFG_DEBUG_NOTFOUND`` environment variable or the ``debug_notfound`` configuration file setting. -Details of why a view was not found will be printed to stderr, and the -browser representation of the error will include the same information. -See :ref:`environment_chapter` for more information about how and -where to set these values. +Details of why a view was not found will be printed to ``stderr``, and +the browser representation of the error will include the same +information. See :ref:`environment_chapter` for more information +about how and where to set these values. A Traversal Example ------------------- @@ -189,27 +191,29 @@ traversing the follwing graph:: Here's what happens: -- bfg traverses the root, and attempts to find foo, which it finds. +- :mod:`repoze.bfg` traverses the root, and attempts to find foo, + which it finds. -- bfg traverses foo, and attempts to find bar, which it finds. +- :mod:`repoze.bfg` traverses foo, and attempts to find bar, which it + finds. -- bfg traverses bar, and attempts to find baz, which it does not - find ('bar' raises a ``KeyError`` when asked for baz). +- :mod:`repoze.bfg` traverses bar, and attempts to find baz, which it + does not find ('bar' raises a ``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 "context" is bar (the context is the last item found during - traversal). +- the :term:`context` is bar (the context is the last item found + during traversal). -- the "view name" is ``baz`` +- the :term:`view name` is ``baz`` -- the "subpath" is ``('biz', 'buz.txt')`` +- the :term:`subpath` is ``('biz', 'buz.txt')`` -Because it's the "context", bfg examimes "bar" to find out what "type" -it is. Let's say it finds that the context is an ``IBar`` type -(because "bar" happens to have an attribute attached to it that -indicates it's an ``IBar``). +Because it's the "context", :mod:`repoze.bfg` examimes "bar" to find +out what "type" it is. Let's say it finds that the context is an +``IBar`` type (because "bar" happens to have an attribute attached to +it that indicates it's an ``IBar``). Using the "view name" ("baz") and the type, it asks the :term:`application registry` (configured separately, via @@ -218,8 +222,8 @@ Using the "view name" ("baz") and the type, it asks the - Please find me a :term:`view` with the name "baz" that can be used for the type ``IBar``. -Let's say it finds no matching view type. It then returns a -``NotFound``. The request ends. Everyone is sad. +Let's say it finds no matching view type. It then returns the result +of the ``notfound`` view. The request ends. Everyone is sad. But! For this graph:: @@ -235,28 +239,32 @@ But! For this graph:: The user asks for ``http://example.com/foo/bar/baz/biz/buz.txt`` -- bfg traverses foo, and attempts to find bar, which it finds. +- :mod:`repoze.bfg` traverses foo, and attempts to find bar, which it + finds. -- bfg traverses bar, and attempts to find baz, which it finds. +- :mod:`repoze.bfg` traverses bar, and attempts to find baz, which it + finds. -- bfg traverses baz, and attempts to find biz, which it finds. +- :mod:`repoze.bfg` traverses baz, and attempts to find biz, which it + finds. -- bfg traverses biz, and attemtps to find "buz.txt" which it does - not find. +- :mod:`repoze.bfg` traverses biz, and attemtps 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 "context" is biz (the context is the last item found during traversal). +- the :term:`context` is biz (the context is the last item found + during traversal). -- the "view name" is "buz.txt" +- the :term:`view name` is "buz.txt" -- the "subpath" is an empty sequence ( ``()`` ). +- the :term:`subpath` is an empty sequence ( ``()`` ). -Because it's the "context", bfg examimes "biz" to find out what "type" -it is. Let's say it finds that the context an ``IBiz`` type (because -"biz" happens to have an attribute attached to it that happens -indicates it's an ``IBiz``). +Because it's the "context", :mod:`repoze.bfg` examimes "biz" to find +out what "type" it is. Let's say it finds that the context an ``IBiz`` +type (because "biz" happens to have an attribute attached to it that +happens indicates it's an ``IBiz``). Using the "view name" ("buz.txt") and the type, it asks the :term:`application registry` this question: @@ -272,9 +280,9 @@ It is passed the "biz" object as the "context" and the current There are two special cases: -- During traversal you will often end up with a "view name" that is - the empty string. This indicates that :mod:`repoze.bfg` should look - up the *default view*. The default view is a view that is +- During traversal you will often end up with a :term:`view name` that + is the empty string. This indicates that :mod:`repoze.bfg` should + look up the *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. @@ -326,10 +334,13 @@ used to traverse to the virtual root object. See Unicode and Traversal --------------------- -The traversal machinery by default attempts to decode each path -element in ``PATH_INFO`` from its natural byte string (``str`` type) -representation into Unicode using the UTF-8 encoding before passing it -to the ``__getitem__`` of a model object. If any path segment in -``PATH_INFO`` is not decodeable using the UTF-8 decoding, a TypeError -is raised. +The traversal machinery by default attempts to first URL-unquote and +then Unicode-decode each path element in ``PATH_INFO`` from its +natural byte string (``str`` type) representation. URL unquoting is +performed using the Python stdlib ``urllib.unquote`` function. +Conversion from a URL-decoded string into Unicode is attempted using +the UTF-8 encoding. If any URL-unquoted path segment in ``PATH_INFO`` +is not decodeable using the UTF-8 decoding, a TypeError is raised. A +segment will be fully URL-unquoted and UTF8-decoded before it is +passed it to the ``__getitem__`` of any model object during traversal. |
