Files
pecan/docs/source/routing.rst
2011-03-11 00:22:30 -05:00

4.7 KiB

Routing

When a user requests a Pecan-powered page how does Pecan know which controller to use? Pecan uses a method known as Object-dispatch to map a HTTP request to a controller. Obejct-dispatch begins by spliting the path into a list of components and then walking object path starting at the root controller. Let's look at a simple store application: :

from pecan import expose

class BooksController(object):
    @expose()
    def index(self):
        return "Welcome to book section."

    @expose()
    def bestsellers(self):
        return "We have 5 books in the top 10."

class CatalogController(object):
    @expose()
    def index(self):
        return "Welcome to the catalog."

    books = BooksController()

class RootController(object):
    @expose()
    def index(self):
        return "Welcome to store.example.com!"

    @expose()
    def hours(self):
        return "Open 24/7 on the web."

    catalog = CatalogController()

A request for /catalog/books/bestsellers from the online store would begin by Pecan breaking the request up into catalog, books, and bestsellers. Next, Pecan would then lookup catalog on the root controller. Using the catalog object, Pecan would then lookup books followed by bestsellers. What if the URL ends in a slash? Pecan will check for an index method on the current object. In the example above, you may have noticed the expose decorator.

Routing Algorithm

_lookup

::

from pecan import expose

from mymodel import get_student_by_name

class StudentController(object):
def __init(self, person):

self.student = student

@expose() def name(self): return self.student.name

class ClassController(object):

@expose() def _lookup(self, name, *remainder): student = get_student_by_name(name) if student: return StudentController(student, remainder) else: abort(404)

_default

::

from pecan import expose

class RootController(object):

@expose() def hello(self): return 'hello'

@expose(): def bonjour(self): return 'bonjour'

@expose(): def _default(self): return 'I cannot say hi in that language'

_route

::

from pecan import expose

Controller Args

::

from pecan import expose

class RootController(object):

@expose() def say(self, msg): return msg

Client requests /say/hi the controller returns "hi".

:: from pecan import expose

class RootController(object):

@expose(): def say(self, msg=None): if msg is None: return "I not sure what to say" else: return msg

Client requests /say?msg=hello the controller returns "hello".

Generic Functions

::

from pecan import expose

class RootController(object):

@expose(generic=True) def index(self): pass

@index.when(method='POST'): def index_post(self): pass

@index.when(method='GET'): def index_get(self): pass

Helper Functions

redirect abort

@expose

At its core, expose is how you tell Pecan which methods in a class are controllers. expose accepts eight optional parameters some of which can impact routing. :

def expose(template    = None,
       content_type    = 'text/html',
       schema          = None,
       json_schema     = None,
       variable_decode = False,
       error_handler   = None,
       htmlfill        = None,
       generic         = False):

Let's look at an example using template and content_type:

from pecan import decorators

class RootController(object):
    @expose('json')
    @expose('text_template.mako', content_type='text/plain')
    @expose('html_template.mako')
    def hello(self):
        return {'msg': 'Hello!'}

You'll notice that we used three expose decorators. The first tells Pecan to serialize dict using JSON serialization when the client requests /hello.json. The second tells the templating engine to use text_template.mako when the client request /hello.txt. The third tells Pecan to use the html_template.mako when the client requests /hello.html. If the client requests /hello, Pecan will use the text/html template.

Advanced Routing

Hooks Security REST Controller