From 6ce1e0cf1a141767ee0aca70786c15dd993347c5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 20 Jul 2011 06:10:38 -0400 Subject: add more index markers --- docs/narr/muchadoabouttraversal.rst | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'docs/narr/muchadoabouttraversal.rst') diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst index a4709ef18..6ad33c1ce 100644 --- a/docs/narr/muchadoabouttraversal.rst +++ b/docs/narr/muchadoabouttraversal.rst @@ -39,6 +39,9 @@ web developer so you know when you might want to use them. :term:`Traversal` is actually a straightforward metaphor easily comprehended by anyone who's ever used a run-of-the-mill file system with folders and files. +.. index:: + single: URL dispatch + URL Dispatch ------------ @@ -100,12 +103,12 @@ from this process to the client as the final result. The server configuration specified which files would trigger some dynamic code, with the default case being to just serve the static file. +.. index:: + single: traversal + Traversal (aka Resource Location) --------------------------------- -.. index:: - single: traversal overview - Believe it or not, if you understand how serving files from a file system works, you understand traversal. And if you understand that a server might do something different based on what type of file a given request specifies, @@ -141,6 +144,9 @@ generated anywhere along the way, :app:`Pyramid` will return 404. (This isn't precisely true, as you'll see when we learn about view lookup below, but the basic idea holds.) +.. index:: + single: resource + What Is a "Resource"? --------------------- @@ -194,6 +200,9 @@ system. Traversal is in fact a superset of file system lookup. .. note:: See the chapter entitled :ref:`resources_chapter` for a more technical overview of resources. +.. index:: + single: view lookup + View Lookup ----------- -- cgit v1.2.3 From 012b9762cd0b114b6afbf2d6356554b51706804a Mon Sep 17 00:00:00 2001 From: michr Date: Fri, 23 Sep 2011 18:48:28 -0700 Subject: fixed up all the warning dealing ..note and ..warn added a hide toc for glossary to prevent warnings --- docs/narr/muchadoabouttraversal.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docs/narr/muchadoabouttraversal.rst') diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst index 6ad33c1ce..a948e57cc 100644 --- a/docs/narr/muchadoabouttraversal.rst +++ b/docs/narr/muchadoabouttraversal.rst @@ -313,6 +313,8 @@ don't require it, great: stick with :term:`URL dispatch`. But if you're using :app:`Pyramid` and you ever find that you *do* need to support one of these use cases, you'll be glad you have traversal in your toolkit. -.. note:: It is even possible to mix and match :term:`traversal` with +.. note:: + + It is even possible to mix and match :term:`traversal` with :term:`URL dispatch` in the same :app:`Pyramid` application. See the :ref:`hybrid_chapter` chapter for details. -- cgit v1.2.3 From 88bc1225e5f515e53a6f9d8413441581df191aca Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 24 Oct 2011 03:42:42 -0500 Subject: garden --- docs/narr/muchadoabouttraversal.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docs/narr/muchadoabouttraversal.rst') diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst index a948e57cc..4a249ed0d 100644 --- a/docs/narr/muchadoabouttraversal.rst +++ b/docs/narr/muchadoabouttraversal.rst @@ -4,7 +4,9 @@ Much Ado About Traversal ======================== -.. note:: This chapter was adapted, with permission, from a blog post by `Rob +.. note:: + + This chapter was adapted, with permission, from a blog post by `Rob Miller `_, originally published at http://blog.nonsequitarian.org/2010/much-ado-about-traversal/ . -- cgit v1.2.3 From ada151234b6533f3f46ceedada45ad210cbaed99 Mon Sep 17 00:00:00 2001 From: Paul Winkler Date: Mon, 30 Jan 2012 16:45:00 -0500 Subject: incorrect use of 'whom' --- docs/narr/muchadoabouttraversal.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/muchadoabouttraversal.rst') diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst index 4a249ed0d..4ce8cacfe 100644 --- a/docs/narr/muchadoabouttraversal.rst +++ b/docs/narr/muchadoabouttraversal.rst @@ -15,7 +15,7 @@ Traversal is an alternative to :term:`URL dispatch` which allows .. note:: - Ex-Zope users whom are already familiar with traversal and view lookup + Ex-Zope users who are already familiar with traversal and view lookup conceptually may want to skip directly to the :ref:`traversal_chapter` chapter, which discusses technical details. This chapter is mostly aimed at people who have previous :term:`Pylons` experience or experience in -- cgit v1.2.3 From 3f8e72a2412866ca937d5e95679813c00367ed0a Mon Sep 17 00:00:00 2001 From: Paul Winkler Date: Mon, 30 Jan 2012 17:40:22 -0500 Subject: another 'what is this chapter' note --- docs/narr/muchadoabouttraversal.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/narr/muchadoabouttraversal.rst') diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst index 4ce8cacfe..40d498391 100644 --- a/docs/narr/muchadoabouttraversal.rst +++ b/docs/narr/muchadoabouttraversal.rst @@ -4,6 +4,8 @@ Much Ado About Traversal ======================== +(Or, why you should care about it) + .. note:: This chapter was adapted, with permission, from a blog post by `Rob -- cgit v1.2.3 From a3251ddd6d9a2948fe8e762673ee6f3a6a66ea55 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 22 Mar 2013 21:50:00 +0200 Subject: remove visual noise In addition, we also get syntax highlighting... for free. --- docs/narr/muchadoabouttraversal.rst | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'docs/narr/muchadoabouttraversal.rst') diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst index 40d498391..483b1bb16 100644 --- a/docs/narr/muchadoabouttraversal.rst +++ b/docs/narr/muchadoabouttraversal.rst @@ -168,18 +168,12 @@ hood, when ``adict`` is a dictionary-like object, Python translates ``adict['a']`` to ``adict.__getitem__('a')``. Try doing this in a Python interpreter prompt if you don't believe us: -.. code-block:: text - :linenos: - - Python 2.4.6 (#2, Apr 29 2010, 00:31:48) - [GCC 4.4.3] on linux2 - Type "help", "copyright", "credits" or "license" for more information. - >>> adict = {} - >>> adict['a'] = 1 - >>> adict['a'] - 1 - >>> adict.__getitem__('a') - 1 +>>> adict = {} +>>> adict['a'] = 1 +>>> adict['a'] +1 +>>> adict.__getitem__('a') +1 The dictionary-like root object stores the ids of all of its subresources as -- cgit v1.2.3 From 9dbba32a0895a4a56611a6db55b59e9e461a8c1c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 26 Oct 2015 03:01:59 -0700 Subject: minor grammar, rewrap 79 columns, some .rst syntax fixes --- docs/narr/muchadoabouttraversal.rst | 341 ++++++++++++++++++------------------ 1 file changed, 168 insertions(+), 173 deletions(-) (limited to 'docs/narr/muchadoabouttraversal.rst') diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst index 483b1bb16..3e00a295a 100644 --- a/docs/narr/muchadoabouttraversal.rst +++ b/docs/narr/muchadoabouttraversal.rst @@ -4,44 +4,44 @@ Much Ado About Traversal ======================== -(Or, why you should care about it) +(Or, why you should care about it.) .. note:: - This chapter was adapted, with permission, from a blog post by `Rob - Miller `_, originally published at - http://blog.nonsequitarian.org/2010/much-ado-about-traversal/ . + This chapter was adapted, with permission, from a blog post by `Rob Miller + `_, originally published at + http://blog.nonsequitarian.org/2010/much-ado-about-traversal/. -Traversal is an alternative to :term:`URL dispatch` which allows -:app:`Pyramid` applications to map URLs to code. +Traversal is an alternative to :term:`URL dispatch` which allows :app:`Pyramid` +applications to map URLs to code. .. note:: Ex-Zope users who are already familiar with traversal and view lookup conceptually may want to skip directly to the :ref:`traversal_chapter` - chapter, which discusses technical details. This chapter is mostly aimed - at people who have previous :term:`Pylons` experience or experience in - another framework which does not provide traversal, and need an - introduction to the "why" of traversal. + chapter, which discusses technical details. This chapter is mostly aimed at + people who have previous :term:`Pylons` experience or experience in another + framework which does not provide traversal, and need an introduction to the + "why" of traversal. Some folks who have been using Pylons and its Routes-based URL matching for a long time are being exposed for the first time, via :app:`Pyramid`, to new ideas such as ":term:`traversal`" and ":term:`view lookup`" as a way to route incoming HTTP requests to callable code. Some of the same folks believe that -traversal is hard to understand. Others question its usefulness; URL -matching has worked for them so far, why should they even consider dealing -with another approach, one which doesn't fit their brain and which doesn't -provide any immediately obvious value? +traversal is hard to understand. Others question its usefulness; URL matching +has worked for them so far, so why should they even consider dealing with +another approach, one which doesn't fit their brain and which doesn't provide +any immediately obvious value? You can be assured that if you don't want to understand traversal, you don't have to. You can happily build :app:`Pyramid` applications with only -:term:`URL dispatch`. However, there are some straightforward, real-world -use cases that are much more easily served by a traversal-based approach than -by a pattern-matching mechanism. Even if you haven't yet hit one of these -use cases yourself, understanding these new ideas is worth the effort for any -web developer so you know when you might want to use them. :term:`Traversal` -is actually a straightforward metaphor easily comprehended by anyone who's -ever used a run-of-the-mill file system with folders and files. +:term:`URL dispatch`. However, there are some straightforward, real-world use +cases that are much more easily served by a traversal-based approach than by a +pattern-matching mechanism. Even if you haven't yet hit one of these use cases +yourself, understanding these new ideas is worth the effort for any web +developer so you know when you might want to use them. :term:`Traversal` is +actually a straightforward metaphor easily comprehended by anyone who's ever +used a run-of-the-mill file system with folders and files. .. index:: single: URL dispatch @@ -49,34 +49,33 @@ ever used a run-of-the-mill file system with folders and files. URL Dispatch ------------ -Let's step back and consider the problem we're trying to solve. An -HTTP request for a particular path has been routed to our web -application. The requested path will possibly invoke a specific -:term:`view callable` function defined somewhere in our app. We're -trying to determine *which* callable function, if any, should be -invoked for a given requested URL. +Let's step back and consider the problem we're trying to solve. An HTTP +request for a particular path has been routed to our web application. The +requested path will possibly invoke a specific :term:`view callable` function +defined somewhere in our app. We're trying to determine *which* callable +function, if any, should be invoked for a given requested URL. Many systems, including Pyramid, offer a simple solution. They offer the -concept of "URL matching". URL matching approaches this problem by parsing -the URL path and comparing the results to a set of registered "patterns", -defined by a set of regular expressions, or some other URL path templating -syntax. Each pattern is mapped to a callable function somewhere; if the -request path matches a specific pattern, the associated function is called. -If the request path matches more than one pattern, some conflict resolution -scheme is used, usually a simple order precedence so that the first match -will take priority over any subsequent matches. If a request path doesn't -match any of the defined patterns, a "404 Not Found" response is returned. - -In Pyramid, we offer an implementation of URL matching which we call -:term:`URL dispatch`. Using :app:`Pyramid` syntax, we might have a match -pattern such as ``/{userid}/photos/{photoid}``, mapped to a ``photo_view()`` -function defined somewhere in our code. Then a request for a path such as +concept of "URL matching". URL matching approaches this problem by parsing the +URL path and comparing the results to a set of registered "patterns", defined +by a set of regular expressions or some other URL path templating syntax. Each +pattern is mapped to a callable function somewhere; if the request path matches +a specific pattern, the associated function is called. If the request path +matches more than one pattern, some conflict resolution scheme is used, usually +a simple order precedence so that the first match will take priority over any +subsequent matches. If a request path doesn't match any of the defined +patterns, a "404 Not Found" response is returned. + +In Pyramid, we offer an implementation of URL matching which we call :term:`URL +dispatch`. Using :app:`Pyramid` syntax, we might have a match pattern such as +``/{userid}/photos/{photoid}``, mapped to a ``photo_view()`` function defined +somewhere in our code. Then a request for a path such as ``/joeschmoe/photos/photo1`` would be a match, and the ``photo_view()`` function would be invoked to handle the request. Similarly, -``/{userid}/blog/{year}/{month}/{postid}`` might map to a -``blog_post_view()`` function, so ``/joeschmoe/blog/2010/12/urlmatching`` -would trigger the function, which presumably would know how to find and -render the ``urlmatching`` blog post. +``/{userid}/blog/{year}/{month}/{postid}`` might map to a ``blog_post_view()`` +function, so ``/joeschmoe/blog/2010/12/urlmatching`` would trigger the +function, which presumably would know how to find and render the +``urlmatching`` blog post. Historical Refresher -------------------- @@ -88,65 +87,64 @@ time when we didn't have fancy web frameworks like :term:`Pylons` and :app:`Pyramid`. Instead, we had general purpose HTTP servers that primarily served files off of a file system. The "root" of a given site mapped to a particular folder somewhere on the file system. Each segment of the request -URL path represented a subdirectory. The final path segment would be either -a directory or a file, and once the server found the right file it would -package it up in an HTTP response and send it back to the client. So serving -up a request for ``/joeschmoe/photos/photo1`` literally meant that there was -a ``joeschmoe`` folder somewhere, which contained a ``photos`` folder, which -in turn contained a ``photo1`` file. If at any point along the way we find -that there is not a folder or file matching the requested path, we return a -404 response. +URL path represented a subdirectory. The final path segment would be either a +directory or a file, and once the server found the right file it would package +it up in an HTTP response and send it back to the client. So serving up a +request for ``/joeschmoe/photos/photo1`` literally meant that there was a +``joeschmoe`` folder somewhere, which contained a ``photos`` folder, which in +turn contained a ``photo1`` file. If at any point along the way we find that +there is not a folder or file matching the requested path, we return a 404 +response. As the web grew more dynamic, however, a little bit of extra complexity was -added. Technologies such as CGI and HTTP server modules were developed. -Files were still looked up on the file system, but if the file ended with -(for example) ``.cgi`` or ``.php``, or if it lived in a special folder, -instead of simply sending the file to the client the server would read the -file, execute it using an interpreter of some sort, and then send the output -from this process to the client as the final result. The server -configuration specified which files would trigger some dynamic code, with the -default case being to just serve the static file. +added. Technologies such as CGI and HTTP server modules were developed. Files +were still looked up on the file system, but if the file ended with (for +example) ``.cgi`` or ``.php``, or if it lived in a special folder, instead of +simply sending the file to the client the server would read the file, execute +it using an interpreter of some sort, and then send the output from this +process to the client as the final result. The server configuration specified +which files would trigger some dynamic code, with the default case being to +just serve the static file. .. index:: single: traversal -Traversal (aka Resource Location) ---------------------------------- +Traversal (a.k.a., Resource Location) +------------------------------------- Believe it or not, if you understand how serving files from a file system works, you understand traversal. And if you understand that a server might do -something different based on what type of file a given request specifies, -then you understand view lookup. +something different based on what type of file a given request specifies, then +you understand view lookup. The major difference between file system lookup and traversal is that a file -system lookup steps through nested directories and files in a file system -tree, while traversal steps through nested dictionary-type objects in a -:term:`resource tree`. Let's take a detailed look at one of our example -paths, so we can see what I mean: - -The path ``/joeschmoe/photos/photo1``, has four segments: ``/``, -``joeschmoe``, ``photos`` and ``photo1``. With file system lookup we might -have a root folder (``/``) containing a nested folder (``joeschmoe``), which -contains another nested folder (``photos``), which finally contains a JPG -file (``photo1``). With traversal, we instead have a dictionary-like root -object. Asking for the ``joeschmoe`` key gives us another dictionary-like -object. Asking this in turn for the ``photos`` key gives us yet another -mapping object, which finally (hopefully) contains the resource that we're -looking for within its values, referenced by the ``photo1`` key. - -In pure Python terms, then, the traversal or "resource location" -portion of satisfying the ``/joeschmoe/photos/photo1`` request -will look something like this pseudocode:: +system lookup steps through nested directories and files in a file system tree, +while traversal steps through nested dictionary-type objects in a +:term:`resource tree`. Let's take a detailed look at one of our example paths, +so we can see what I mean. + +The path ``/joeschmoe/photos/photo1``, has four segments: ``/``, ``joeschmoe``, +``photos`` and ``photo1``. With file system lookup we might have a root folder +(``/``) containing a nested folder (``joeschmoe``), which contains another +nested folder (``photos``), which finally contains a JPG file (``photo1``). +With traversal, we instead have a dictionary-like root object. Asking for the +``joeschmoe`` key gives us another dictionary-like object. Asking in turn for +the ``photos`` key gives us yet another mapping object, which finally +(hopefully) contains the resource that we're looking for within its values, +referenced by the ``photo1`` key. + +In pure Python terms, then, the traversal or "resource location" portion of +satisfying the ``/joeschmoe/photos/photo1`` request will look something like +this pseudocode:: get_root()['joeschmoe']['photos']['photo1'] -``get_root()`` is some function that returns a root traversal -:term:`resource`. If all of the specified keys exist, then the returned -object will be the resource that is being requested, analogous to the JPG -file that was retrieved in the file system example. If a :exc:`KeyError` is -generated anywhere along the way, :app:`Pyramid` will return 404. (This -isn't precisely true, as you'll see when we learn about view lookup below, -but the basic idea holds.) +``get_root()`` is some function that returns a root traversal :term:`resource`. +If all of the specified keys exist, then the returned object will be the +resource that is being requested, analogous to the JPG file that was retrieved +in the file system example. If a :exc:`KeyError` is generated anywhere along +the way, :app:`Pyramid` will return 404. (This isn't precisely true, as you'll +see when we learn about view lookup below, but the basic idea holds.) .. index:: single: resource @@ -159,10 +157,10 @@ nested dictionary things? Where do these objects, these 'resources', live? What *are* they?" Since :app:`Pyramid` is not a highly opinionated framework, it makes no -restriction on how a :term:`resource` is implemented; a developer can -implement them as he wishes. One common pattern used is to persist all of -the resources, including the root, in a database as a graph. The root object -is a dictionary-like object. Dictionary-like objects in Python supply a +restriction on how a :term:`resource` is implemented; a developer can implement +them as they wish. One common pattern used is to persist all of the resources, +including the root, in a database as a graph. The root object is a +dictionary-like object. Dictionary-like objects in Python supply a ``__getitem__`` method which is called when key lookup is done. Under the hood, when ``adict`` is a dictionary-like object, Python translates ``adict['a']`` to ``adict.__getitem__('a')``. Try doing this in a Python @@ -175,25 +173,24 @@ interpreter prompt if you don't believe us: >>> adict.__getitem__('a') 1 - The dictionary-like root object stores the ids of all of its subresources as keys, and provides a ``__getitem__`` implementation that fetches them. So ``get_root()`` fetches the unique root object, while ``get_root()['joeschmoe']`` returns a different object, also stored in the database, which in turn has its own subresources and ``__getitem__`` -implementation, etc. These resources might be persisted in a relational +implementation, and so on. These resources might be persisted in a relational database, one of the many "NoSQL" solutions that are becoming popular these -days, or anywhere else, it doesn't matter. As long as the returned objects -provide the dictionary-like API (i.e. as long as they have an appropriately -implemented ``__getitem__`` method) then traversal will work. - -In fact, you don't need a "database" at all. You could use plain -dictionaries, with your site's URL structure hard-coded directly in -the Python source. Or you could trivially implement a set of objects -with ``__getitem__`` methods that search for files in specific -directories, and thus precisely recreate the traditional mechanism of -having the URL path mapped directly to a folder structure on the file -system. Traversal is in fact a superset of file system lookup. +days, or anywhere else; it doesn't matter. As long as the returned objects +provide the dictionary-like API (i.e., as long as they have an appropriately +implemented ``__getitem__`` method), then traversal will work. + +In fact, you don't need a "database" at all. You could use plain dictionaries, +with your site's URL structure hard-coded directly in the Python source. Or +you could trivially implement a set of objects with ``__getitem__`` methods +that search for files in specific directories, and thus precisely recreate the +traditional mechanism of having the URL path mapped directly to a folder +structure on the file system. Traversal is in fact a superset of file system +lookup. .. note:: See the chapter entitled :ref:`resources_chapter` for a more technical overview of resources. @@ -208,34 +205,33 @@ At this point we're nearly there. We've covered traversal, which is the process by which a specific resource is retrieved according to a specific URL path. But what is "view lookup"? -The need for view lookup is simple: there is more than one possible action -that you might want to take after finding a :term:`resource`. With our photo +The need for view lookup is simple: there is more than one possible action that +you might want to take after finding a :term:`resource`. With our photo example, for instance, you might want to view the photo in a page, but you might also want to provide a way for the user to edit the photo and any associated metadata. We'll call the former the ``view`` view, and the latter will be the ``edit`` view. (Original, I know.) :app:`Pyramid` has a centralized view :term:`application registry` where named views can be -associated with specific resource types. So in our example, we'll assume -that we've registered ``view`` and ``edit`` views for photo objects, and that -we've specified the ``view`` view as the default, so that +associated with specific resource types. So in our example, we'll assume that +we've registered ``view`` and ``edit`` views for photo objects, and that we've +specified the ``view`` view as the default, so that ``/joeschmoe/photos/photo1/view`` and ``/joeschmoe/photos/photo1`` are equivalent. The edit view would sensibly be provided by a request for ``/joeschmoe/photos/photo1/edit``. Hopefully it's clear that the first portion of the edit view's URL path is -going to resolve to the same resource as the non-edit version, specifically -the resource returned by ``get_root()['joeschmoe']['photos']['photo1']``. -But traveral ends there; the ``photo1`` resource doesn't have an ``edit`` -key. In fact, it might not even be a dictionary-like object, in which case +going to resolve to the same resource as the non-edit version, specifically the +resource returned by ``get_root()['joeschmoe']['photos']['photo1']``. But +traversal ends there; the ``photo1`` resource doesn't have an ``edit`` key. In +fact, it might not even be a dictionary-like object, in which case ``photo1['edit']`` would be meaningless. When the :app:`Pyramid` resource location has been resolved to a *leaf* resource, but the entire request path has not yet been expended, the *very next* path segment is treated as a -:term:`view name`. The registry is then checked to see if a view of the -given name has been specified for a resource of the given type. If so, the -view callable is invoked, with the resource passed in as the related -``context`` object (also available as ``request.context``). If a view -callable could not be found, :app:`Pyramid` will return a "404 Not Found" -response. +:term:`view name`. The registry is then checked to see if a view of the given +name has been specified for a resource of the given type. If so, the view +callable is invoked, with the resource passed in as the related ``context`` +object (also available as ``request.context``). If a view callable could not +be found, :app:`Pyramid` will return a "404 Not Found" response. You might conceptualize a request for ``/joeschmoe/photos/photo1/edit`` as ultimately converted into the following piece of Pythonic pseudocode:: @@ -246,8 +242,8 @@ ultimately converted into the following piece of Pythonic pseudocode:: view_callable(request) The ``get_root`` and ``get_view`` functions don't really exist. Internally, -:app:`Pyramid` does something more complicated. But the example above -is a reasonable approximation of the view lookup algorithm in pseudocode. +:app:`Pyramid` does something more complicated. But the example above is a +reasonable approximation of the view lookup algorithm in pseudocode. Use Cases --------- @@ -261,58 +257,57 @@ like this:: /{userid}/{typename}/{objectid}[/{view_name}] -In all of the examples thus far, we've hard coded the typename value, -assuming that we'd know at development time what names were going to be used -("photos", "blog", etc.). But what if we don't know what these names will -be? Or, worse yet, what if we don't know *anything* about the structure of -the URLs inside a user's folder? We could be writing a CMS where we want the -end user to be able to arbitrarily add content and other folders inside his -folder. He might decide to nest folders dozens of layers deep. How will you -construct matching patterns that could account for every possible combination -of paths that might develop? - -It might be possible, but it certainly won't be easy. The matching -patterns are going to become complex quickly as you try to handle all -of the edge cases. - -With traversal, however, it's straightforward. Twenty layers of nesting -would be no problem. :app:`Pyramid` will happily call ``__getitem__`` as -many times as it needs to, until it runs out of path segments or until a -resource raises a :exc:`KeyError`. Each resource only needs to know how to -fetch its immediate children, the traversal algorithm takes care of the rest. -Also, since the structure of the resource tree can live in the database and -not in the code, it's simple to let users modify the tree at runtime to set -up their own personalized "directory" structures. - -Another use case in which traversal shines is when there is a need to support -a context-dependent security policy. One example might be a document -management infrastructure for a large corporation, where members of different -departments have varying access levels to the various other departments' -files. Reasonably, even specific files might need to be made available to -specific individuals. Traversal does well here if your resources actually -represent the data objects related to your documents, because the idea of a -resource authorization is baked right into the code resolution and calling -process. Resource objects can store ACLs, which can be inherited and/or -overridden by the subresources. - -If each resource can thus generate a context-based ACL, then whenever view -code is attempting to perform a sensitive action, it can check against that -ACL to see whether the current user should be allowed to perform the action. -In this way you achieve so called "instance based" or "row level" security -which is considerably harder to model using a traditional tabular approach. +In all of the examples thus far, we've hard coded the typename value, assuming +that we'd know at development time what names were going to be used ("photos", +"blog", etc.). But what if we don't know what these names will be? Or, worse +yet, what if we don't know *anything* about the structure of the URLs inside a +user's folder? We could be writing a CMS where we want the end user to be able +to arbitrarily add content and other folders inside his folder. He might +decide to nest folders dozens of layers deep. How will you construct matching +patterns that could account for every possible combination of paths that might +develop? + +It might be possible, but it certainly won't be easy. The matching patterns +are going to become complex quickly as you try to handle all of the edge cases. + +With traversal, however, it's straightforward. Twenty layers of nesting would +be no problem. :app:`Pyramid` will happily call ``__getitem__`` as many times +as it needs to, until it runs out of path segments or until a resource raises a +:exc:`KeyError`. Each resource only needs to know how to fetch its immediate +children, and the traversal algorithm takes care of the rest. Also, since the +structure of the resource tree can live in the database and not in the code, +it's simple to let users modify the tree at runtime to set up their own +personalized "directory" structures. + +Another use case in which traversal shines is when there is a need to support a +context-dependent security policy. One example might be a document management +infrastructure for a large corporation, where members of different departments +have varying access levels to the various other departments' files. +Reasonably, even specific files might need to be made available to specific +individuals. Traversal does well here if your resources actually represent the +data objects related to your documents, because the idea of a resource +authorization is baked right into the code resolution and calling process. +Resource objects can store ACLs, which can be inherited and/or overridden by +the subresources. + +If each resource can thus generate a context-based ACL, then whenever view code +is attempting to perform a sensitive action, it can check against that ACL to +see whether the current user should be allowed to perform the action. In this +way you achieve so called "instance based" or "row level" security which is +considerably harder to model using a traditional tabular approach. :app:`Pyramid` actively supports such a scheme, and in fact if you register -your views with guard permissions and use an authorization policy, -:app:`Pyramid` can check against a resource's ACL when deciding whether or -not the view itself is available to the current user. +your views with guarded permissions and use an authorization policy, +:app:`Pyramid` can check against a resource's ACL when deciding whether or not +the view itself is available to the current user. -In summary, there are entire classes of problems that are more easily served -by traversal and view lookup than by :term:`URL dispatch`. If your problems -don't require it, great: stick with :term:`URL dispatch`. But if you're -using :app:`Pyramid` and you ever find that you *do* need to support one of -these use cases, you'll be glad you have traversal in your toolkit. +In summary, there are entire classes of problems that are more easily served by +traversal and view lookup than by :term:`URL dispatch`. If your problems don't +require it, great, stick with :term:`URL dispatch`. But if you're using +:app:`Pyramid` and you ever find that you *do* need to support one of these use +cases, you'll be glad you have traversal in your toolkit. .. note:: - It is even possible to mix and match :term:`traversal` with - :term:`URL dispatch` in the same :app:`Pyramid` application. See the + It is even possible to mix and match :term:`traversal` with :term:`URL + dispatch` in the same :app:`Pyramid` application. See the :ref:`hybrid_chapter` chapter for details. -- cgit v1.2.3