Route and View Examples

Here are the most common kinds of routes and views.

  1. Fixed controller and action.

    1# Pylons
    2map.connect("faq", "/help/faq", controller="help", action="faq")
    3class HelpController(Base):
    4    def faq(self):
    5        ...
    
    1# Pyramid
    2config.add_route("faq", "/help/faq")
    3@view_config(route_name="faq", renderer="...")
    4def faq(self):   # In some arbitrary class.
    5    ...
    

    .

  2. Fixed controller and action, plus other routing variables.

    1# Pylons
    2map.connect("article", "/article/{id}", controller="foo",
    3    action="article")
    4class FooController(Base):
    5    def article(self, id):
    6        ...
    
    1# Pyramid
    2config.add_route("article", "/article/{id}")
    3@view_config(route_name="article")
    4def article(self):   # In some arbitrary class.
    5    id = self.request.matchdict["id"]
    

    .

  3. Variable controller and action.

    # Pylons
    map.connect("/{controller}/{action}")
    map.connect("/{controller/{action}/{id}")
    
    # Pyramid
    # Not possible.
    

    You can't choose a view class via a routing variable in Pyramid.

  4. Fixed controller, variable action.

    # Pylons
    map.connect("help", "/help/{action}", controller="help")
    
    1# Pyramid
    2config.add_route("help", "/help/{action}")
    3
    4@view_config(route_name="help", match_param="action=help", ...)
    5def help(self):   # In some arbitrary class.
    6    ...
    

    The 'pyramid_handlers' package provides an alternative for this.

Other Pyramid examples:

1# Home route.
2config.add_route("home", "/")
3
4# Multi-action route, excluding certain static URLs.
5config.add_route("main", "/{action}",
6    path_info=r"/(?!favicon\.ico|robots\.txt|w3c)")

pyramid_handlers

"pyramid_handlers" is an add-on package that provides a possibly more convenient way to handle case #4 above, a route with an 'action' variable naming a view. It works like this:

 1# In the top-level __init__.py
 2from .handlers import Hello
 3def main(global_config, **settings):
 4    ...
 5    config.include("pyramid_handlers")
 6    config.add_handler("hello", "/hello/{action}", handler=Hello) 
 7
 8# In zzz/handlers.py
 9from pyramid_handlers import action
10class Hello(object):
11    __autoexpose__ = None
12
13    def __init__(self, request):
14        self.request = request
15
16    @action
17    def index(self):
18        return Response('Hello world!')
19
20    @action(renderer="mytemplate.mak")
21    def bye(self):
22        return {}

The add_handler method (line 6) registers the route and then scans the Hello class. It registers as views all methods that have an @action decorator, using the method name as a view predicate, so that when that method name appears in the 'action' part of the URL, Pyramid calls this view.

The __autoexpose__ class attribute (line 11) can be a regex. If any method name matches it, it will be registered as a view even if it doesn't have an @action decorator. The default autoexpose regex matches all methods that begin with a letter, so you'll have to set it to None to prevent methods from being automatically exposed. You can do this in a base class if you wish.

Note that @action decorators are not recognized by config.scan(). They work only with config.add_hander.

User reaction to "pyramid_handlers" has been mixed. A few people are using it, but most people use @view_config because it's "standard Pyramid".

Resouce routes

"pyramid_routehelper" provides a config.add_resource method that behaves like Pylons' map.resource. It adds a suite of routes to list/view/add/modify/delete a resource in a RESTful manner (following the Atom publishing protocol). See the source docstrings in the link for details.

Note: the word "resource" here is not related to traversal resources.