On Fri, 2010-12-03 at 17:33 -0800, Seth wrote:
> I've been a TurboGears user for most of my projects but have just been
> hired to start a new Pyramid project. Naturally, I'm interested in the
> traversal approach to views and routes, but am having trouble figuring
> out from the documentation exactly how traversal would work when
> spanning across multiple view classes/modules.
> 
> 
> Let's look at this typical TurboGears setup, for example (loosely
> adapted to Pyramid):
> 
> --> The main root factory (myapp/views/root.py): <--
> from myapp.views.admin.root import AdminRootView
> 
> class RootView(object):
>     def __init__(self, request):
>         self.request = request
> 
>     admin = AdminRootView
> 
>     @view_config(renderer='string')
>     def index(self):
>         return 'index'
> 
> 
> --> The admin root (myapp/views/admin/root.py): <--
> class AdminRootView(object):
>     def __init__(self, request):
>         self.request = request
> 
> 
>     @view_config(renderer='string')
>     def index(self):
>         return 'admin index'
> 
>     @view_config(name='hello', renderer='string')
>     def hello(self):
>         return 'admin hello'
> 
> 
> 
> Of course, in a TurboGears-style setup, this would expose views for
> example.com, example.com/admin/, and example.com/admin/hello. However,
> in Pyramid the views for the "sub-views" (/admin/*) don't seem to be
> able to be found. I have succeeded in making this approach work by
> using a "hybrid" setup (using add_route in the config and a
> "route_name" parameter in the view_config), but I can't help but think
> that there's got to be an easier way to do this and I'm just missing
> something.
> 
> 
> So, is this not really the intended use for traversal? The examples I
> found in the docs about classed-based traversal only go 1-layer deep
> (a Root class). I couldn't seem to land on anything solid explaining a
> larger app setup with views in their own subdirectory and hierarchical
> parent/child classes as separately traversed views. Am I making things
> too verbose, or am I just missing a piece of the puzzle?

Pyramid traversal and TurboGears object dispatch work very differently.
In Pyramid, the graph of objects traversed isnt consulted for view
logic.  Instead, the graph is a graph of "model" objects.  "Traversal"
is the act of finding a "context".  When a context is found, traversal
has done its job.  Subsequently a view is looked up based on that
context and data in the request.

An analogue of your above might look like so in Pyramid:

#--> The main root factory (myapp/views/root.py): <--
from pyramid.view import view_config
from pyramid.configuration import Configurator
from paste.httpserver import serve

class AdminModel(object):
    pass

class RootView(object):
    def __init__(self, request):
        self.request = request

    @view_config(renderer='string')
    def __call__(self):
        return 'index'

#--> The admin root (myapp/views/admin/root.py): <--
class AdminRootView(object):
    def __init__(self, request):
        self.request = request

    @view_config(renderer='string', context=AdminModel)
    def __call__(self):
        return 'admin index'

    @view_config(name='hello', renderer='string', context=AdminModel)
    def hello(self):
        return 'admin hello'

root = {'admin':AdminModel()}

if __name__ == '__main__':
    config = Configurator(root_factory = lambda x: root)
    config.scan()
    app = config.make_wsgi_app()
    serve(app)

The root object represents the root of the graph being traversed.  The
AdminModel object is present in the graph under the root as the key
"admin".

When traversal traverses "/", the context is the root.  Since every
other view is registered for a more specific context, the Root View is
used.

    http://localhost:8080/ -> 'index'

When traversal traverses "/admin", the context is the "admin"
AdminModel.  Only the views registered for this context will be
considered viable.  Since the "view name" is "", the view registered as
"__call__" (no name= argument) on the AdminRootView object will be used:

    http://localhost:8080/admin -> 'admin index'

When traversal traverses "/admin/hello", the context is the "admin"
AdminModel.  Since the view name is "hello", the view registered as
name="hello" (the hello method of the AdminRootView) will be used.

    http://localhost:8080/admin/hello -> 'admin hello'

For more info, see the Traversal chapter in the Pyramid docs:
http://docs.pylonshq.com/pyramid/dev/narr/traversal.html

- C


-- 
You received this message because you are subscribed to the Google Groups 
"pylons-devel" group.
To post to this group, send email to pylons-de...@googlegroups.com.
To unsubscribe from this group, send email to 
pylons-devel+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/pylons-devel?hl=en.

Reply via email to