URL dispatch vs traversal

151 views
Skip to first unread message

Mike Orr

unread,
Nov 23, 2010, 10:35:33 PM11/23/10
to pylons...@googlegroups.com
I wonder if it would be clearer to to put the URL Dispatch chapter
before Context Finding and Traversal in the manual. URL Dispatch seems
to be simpler, and it doesn't require learning about the root object,
context object, and context finding only to learn you won't be using
them. It seems like URL Dispatch can be presented in a way that people
will see immediately if they're not using it, without having to pore
through the abstract concepts of "context finding" and "view lookup".
Then if they want to use traversal or learn about these objects, they
can learn about them afterward, otherwise they can skip those two
chapters.

--
Mike Orr <slugg...@gmail.com>

Chris McDonough

unread,
Nov 23, 2010, 11:00:07 PM11/23/10
to pylons...@googlegroups.com

I sympathize with this, and I think we can probably organize it better.
Casey Duncan is currently working on editing the book as a for-pay sort
of thing. I'm hoping he'll come up with some concrete suggestions as to
how to reorganize things, but maybe I can put a bug in his ear along the
lines of your suggestion.

FTR, it would be more technically accurate to say that users *will* be
using a root object, a context object, and context finding when he uses
URL dispatch, but he can mostly ignore their existence. URL dispatch
literally is a context finding mechanism. This is why the docs are
organized as they are now.

OTOH, users do indeed need to know about view lookup even if they only
use URL dispatch. A matched route doesn't always imply the lookup of
one single canonical view. For example, if a route matches, it might go
to one view if the request method is POST, another if the request method
is GET.

- C

Mike Orr

unread,
Nov 23, 2010, 11:21:57 PM11/23/10
to pylons...@googlegroups.com

OK, I think we can handle this in a short paragraph at the beginning
of the URL Dispatch chapter. Just quickly explain in passing what
these are and that the'll be covered more in depth in the following
chapters. Currently the "Context Finding and View Lookup" chapter and
the "Traversal" chapter are the most confusing parts of the manual to
Pylons users; they make the framework seem foreign and hard to grasp.
You have to make your way through nine dense paragraphs and a section
on which mechanism to use, and then if you start reading the traversal
chapter anyway it gets hard to follow with all these new concepts. I
think traversal fans can skim over the URL dispatch chapter easier
than people coming from a Routes background can skim over the two
other chapters.


--
Mike Orr <slugg...@gmail.com>

Mike Orr

unread,
Nov 24, 2010, 1:41:15 AM11/24/10
to pylons...@googlegroups.com
On Tue, Nov 23, 2010 at 8:21 PM, Mike Orr <slugg...@gmail.com> wrote:
> On Tue, Nov 23, 2010 at 8:00 PM, Chris McDonough <chr...@plope.com> wrote:
>> On Tue, 2010-11-23 at 19:35 -0800, Mike Orr wrote:
>>> I wonder if it would be clearer to to put the URL Dispatch chapter
>>> before Context Finding and Traversal in the manual.
>>
>> I sympathize with this, and I think we can probably organize it better.
>> Casey Duncan is currently working on editing the book as a for-pay sort
>> of thing.  I'm hoping he'll come up with some concrete suggestions as to
>> how to reorganize things, but maybe I can put a bug in his ear along the
>> lines of your suggestion.
>>
>> FTR, it would be more technically accurate to say that users *will* be
>> using a root object, a context object, and context finding when he uses
>> URL dispatch, but he can mostly ignore their existence.  URL dispatch
>> literally is a context finding mechanism.  This is why the docs are
>> organized as they are now.
>>
>> OTOH, users do indeed need to know about view lookup even if they only
>> use URL dispatch.  A matched route doesn't always imply the lookup of
>> one single canonical view.  For example, if a route matches, it might go
>> to one view if the request method is POST, another if the request method
>> is GET.
>
> OK, I think we can handle this in a short paragraph at the beginning
> of the URL Dispatch chapter. Just quickly explain in passing what
> these are and that the'll be covered more in depth in the following
> chapters.

Ignore this, I misunderstood your message. You said the user could
remain blissfully unaware of these until they're ready to use them.

How about an outline like this, roughly.


CONTEXT FINDING AND VIEW LOOKUP
--------------------------------------------------
This section is about how Pyramid maps a user request (the URL plus
certain other info included in the request) to a *view callable*. A
view callable is a piece of code that takes a request and produces a
response, such as an HTML page or a multimedia object. In Pyramid, the
request and response are instances of Request and Response classes.
Most Pyramid applications have several view callables, each one
corresponding to a different kind of URL. View callables can also be
grouped into *handlers*, where the handler is a class and the view
callables are methods in that class.

Pyramid provides two different ways to map a URL to a view callable.
One is called URL Dispatch, familiar to Pylons and Routes users. It
matches the entire URL against a set of rules known as *routes*, and
the first matching route specifies which view callable to invoke. The
other way is called Traversal, which is familiar to BFG, TurboGears,
and Zope users. Traversal matches each URL component against keys of a
dict-like root object, recursively mapping components to keys until a
view callable is identified. An application can use one way, the other
way, or both in different situations. The next chapter explains URL
Dispatch; the following chapter covers Traversal. The N+3 chapter
discusses hybrid applications using both URL Dispatch and Traversal.
The N+4 chapter explains view callables in detail.

[Move "What good is a context finding subsystem" and "Should I use
traversal or URL dispatch" to traversal chapter.]

URL DISPATCH
-------------------
Simple example mentioning 'add_route' and 'add_handler' (for both URL
dispatch and traversal readers, so they recognize the methods when
they see them)

Traversal readers can now skip to the next chapter

API, basic, and advanced usages

It may be helpful to introduce a minimal view callable and handler, so
that people can get a concrete feel for how the routing and view
callables interact.

Mention that a *context* exists, and explain it in URL Dispatch terms.
The context contains additional information about the user's
environment not included in the request. The context is mainly useful
with Traversal, Normally all URL Dispatch requests use the same
default context, but if you're using auth you may have to explicity
specify a context; see the Auth chapter for details.

TRAVERSAL AND HYBRID USAGE
-------------------------------------------

Start with a concise, concrete example, something as easy to grasp as
a CherryPy root. Mention the characteristic methods: 'add_view'.
('add_model'?)

Explain that Traversal is most useful when the URL refers to an
arbitrary hierachical structure such as an object database (ZODB).
[This replaces the "Should I use Traversal or URL Dispatch" section,
but can be much shorter.]

Shorten the Unix conceptual example. Don't get into shell commands and
what the "inexperienced user" doesn't know. Just show a directory tree
(the complete tree), and imagine cd'ing into each directory and
looking for the next component. .__getitem__ is too abstract;
introduce it by saying the root object is dict-like.

The rest of the chapter can stay pretty much the same.

Most of the context stuff goes here.

HYBRID URL DISPATCH
------------------------------

The "URL Dispatch only" and "Traversal Only" sections move to the
beginning of their respective chapters. Deductive readers like me need
to see concrete syntax early in order to relate to the abstract
concepts.

The rest of the chapter can remain as is, but keep in mind that URL
Dispatch is the default way and Traversal is the alternative way, so
'add_route' should be shown first and then 'add_view' explained in
that context.

OTHER STUFF
-------------------

You'll need to go into detail about contexts, context finding, and the
view lookup subsystem. That can go into either the first chapter or
the traversal chapter, or perhaps into a separate chapter after
hybrid. In the latter case, the first four chapters would explain just
enough to use the systems, and the extra chapter would explain the
conceptual underpinnings, or the reason they are that way.

--
Mike Orr <slugg...@gmail.com>

Chris McDonough

unread,
Nov 24, 2010, 12:08:14 PM11/24/10
to pylons...@googlegroups.com
Thanks for this. I'll refer to it once it comes around on the guitar to
unscrew the views chapter.

- C

jorge....@gmail.com

unread,
Dec 6, 2010, 11:01:12 PM12/6/10
to pylons-devel
On Nov 24, 2:41 am, Mike Orr <sluggos...@gmail.com> wrote:
> Mike Orr <sluggos...@gmail.com>

Definitely a +1

I remember Travesal and context as being the hardest parts for me to
gasp back when I tried repoze.bfg and I also remember it's the most
complex part of the system when you just want to get a view to show at
a URL.

Mike Orr

unread,
Dec 7, 2010, 12:23:50 AM12/7/10
to pylons...@googlegroups.com
On Mon, Dec 6, 2010 at 8:01 PM, jorge....@gmail.com
<jorge....@gmail.com> wrote:
> On Nov 24, 2:41 am, Mike Orr <sluggos...@gmail.com> wrote:
>> the first matching route specifies which view callable to invoke. The
>> other way is called Traversal, which is familiar to BFG, TurboGears,
>> and Zope users.

^^^^^^^^^ Wrong.

This is where I mistakenly equated Traversal with TurboGears dispatch

--
Mike Orr <slugg...@gmail.com>

Daniel Holth

unread,
Dec 7, 2010, 12:50:21 AM12/7/10
to pylons...@googlegroups.com
I don't know what all you guys are smoking with this half-cocked "routes" system. Personally it makes no sense to me. I started developing web pages by putting index.html in a folder, and if I visited that folder I would see index.html. Now I put an object in a nested dict, the framework finds it, and calls a method that happens to live in views.py instead of the class itself using something I can conceptualize as multiple dispatch.

If I click on a .txt in the filesystem the operating system knows to load it with an associated application, if I visit an object in Pyramid the framework knows to run an associated view method. Bam! I love traversal.

Of course it's OK to be used to URL dispatch and Pyramid will accommodate, but do you remember when you saw that first list of regexps in some tutorial? URL dispatch and traversal both add a level of indirection between your URLs and your code. They are a tremendous conceptual leap from the bad but approachable old days of 'put a .php script in a directory'.

Daniel

Paul Everitt

unread,
Dec 7, 2010, 7:47:12 AM12/7/10
to pylons...@googlegroups.com

I'll add a little historical perspective to the traversal approach.
Way, way back, before Zope was Zope and before there was a full ZODB, we
had this approach called "object publishing".

It was Python objects, published on the web. A URL pointed you at an
object. The next hop in the URL pointed you (__getitem__) at a
subobject, which might contain (__getitem__) other objects. Ending in a
(Python) method, which said what to do.

These:

root['acme']['departments']['sales']['budget']['2010'].add_folder()

/acme/departments/sales/budget/2010/add_folder

...were the same thing.

At the time (say, around 1997) we made a flyer with some marketing speak
on it. Two points I remember:

- URLs you can read to your grandma over the phone.
- Database which feels like a filesystem.

Somewhere along the line, __getitem__ and Python objects got labeled
un-Pythonic, in favor of the far more Pythonic square MySQL tables and
regex's. :)

BFG and now Pyramid "favor" neither approach. Nor does it favor ZCML
over convention. Nor does it favor vim over Emacs. The latter being an
oversight, soon to be corrected, as we all know there's only room for one.

For me, Routes is a "steep learning curve", similar to Daniel's
position. For others, traversal and __getitem__ is a steep learning
curve. Fortunately, we now let your chocolate get in my peanut butter
and don't need to choose in the case of One v. Other.

--Paul

Rob Miller

unread,
Dec 11, 2010, 4:24:23 AM12/11/10
to pylons...@googlegroups.com
On 12/07/2010 04:47 AM, Paul Everitt wrote:
>
> I'll add a little historical perspective to the traversal approach. Way, way
> back, before Zope was Zope and before there was a full ZODB, we had this
> approach called "object publishing".
>
> It was Python objects, published on the web. A URL pointed you at an object.
> The next hop in the URL pointed you (__getitem__) at a subobject, which might
> contain (__getitem__) other objects. Ending in a (Python) method, which said
> what to do.
>
> These:
>
> root['acme']['departments']['sales']['budget']['2010'].add_folder()
>
> /acme/departments/sales/budget/2010/add_folder
>
> ...were the same thing.

All in all this worked pretty well, but after a while it got bit old to have
the last piece of your URL directly tied to a method name. You really
shouldn't have to refactor your code when you want to change the name of a
page on your site. Hence the introduction of "view lookup", in use in Pyramid
today, which effectively works something like this:

get_view(root['acme']['departments']['sales']['budget']['2010'], 'add_folder')

-r

Reply all
Reply to author
Forward
0 new messages