Controller

Tori’s framework ships with a based controller, extending from tornado.web.RequestHandler. So, the usage is pretty much the same as you can find in Tornado’s documentation.

Suppose we have the following file structure.:

web/
    __init__.py
    controller.py
    views/
        index.html
        error.html

Create a Controller

Let’s start with create a controller in web/controller.py

# Module: web.controller (web/controller)
from tori.controller import Controller

class HomeController(Controller):
    def get(self, name):
        self.write('Hello, {}.'.format(name))

However, as mentioned earlier, the rendering engine is replaced with Jinja2. By default, the methods render and render_template of Controller are not ready to use.

Enable the Template Engine

Template Engine in Tori Framework is totally optional but enabling is not a big problem.

Before getting started, the integration between the rendering part and the controller part is based on the concept of flexibility where each controller can use any template engine or any source. For instance, two controllers may use two different engines or sources.

First, the decorator tori.decorator.controller.renderer (or @renderer for short) must be imported.

from tori.decorator.controller import renderer

where the only parameter of @renderer is either the name of the package (web.views) or the file path (web/views). In this example, we use the package.

@renderer('web.views')
class HomeController(Controller):
    pass

Note

The file path can be either relative with regard of the current working directory or absolute. However, using the package option is recommended.

Suppose the content of web/views/index.html is

Hello, {{ name }}

Then, we replace self.write(...) with

self.render('index.html', name=name)

There is only one default and reserved variable app with two attributes:

  • app.request: an instance of controller’s request tornado.httpserver.HTTPRequest
  • app.session: a reference to controller’s session getter tori.session.controller.Controller

Using Session

Where Tornado framework provide nothing regarding to session management, Tori integrates the cookie-based session controller.

Note

The session controller works with both secure and non-secure cookies. The secure cookies are highly recommended.

The session controller for the session data for a particular session ID is accessible via the read-only property session of the controller. For example, to get a session key “userId”, you can do by

self.session.get('userId')

from any method of the controller. Please read more from tori.session.controller.Controller.

REST Controller

Tori provides the base controller tori.controller.RestController for CRUD operations. It is however designed strictly for querying, creating, retrieving, updating and deleting data.

To use it, the route pattern must accept only one parameter where it is optional. For example, the route can be

<controller class="web.controller.BlogEntryRestController" pattern="/blog/rest/entry/(.*)"/>

where web.controller.BlogEntryRestController is

class BlogEntryRestController(RestController):
    def list(self):
        # GET /blog/rest/entry/
        # query the list of entries
        pass

    def create(self):
        # POST /blog/rest/entry/
        # create a new entry
        pass

    def retrieve(self, id):
        # GET /blog/rest/entry/ID
        # retrieve the entry by ID
        pass

    def update(self, id):
        # PUT /blog/rest/entry/ID
        # update the entry by ID
        pass

    def remove(self, id)
        # DELETE /blog/rest/entry/ID
        # delete the entry by ID
        pass

Note

The remove method is actual the replacement of the delete method but to minimize the need of users to call the parent/ancestors version of the overridden method, the delete method is tended to be left untouched where the deleting implementation should be placed in the remove method.

Customize Error Page

There are types of custom error pages for normal controllers and error controllers where any custom error pages will receive three variables: message, code (HTTP Response Code) and debug_info (the text version of stack trace).

Custom Error Pages for Unattended Exceptions

When exceptions are raised unexpectedly, to handle the exceptions not handled by normal controllers, you need something similar to the following code.

@custom_error('error.html')
@renderer('app.view')
class ErrorController(BaseErrorController): pass

Then, add a single <error> tag under the <server> tag. For example,

<?xml version="1.0" encoding="utf-8"?>
<application>
    <!-- ... -->
    <server>
        <!-- ... -->
        <error>app.controller.ErrorController</error>
        <!-- ... -->
    </server>
    <!-- ... -->
</application>

Controller-specific Custom Error Pages

When exceptions are raised on a normal controller (e.g., any controller based on tori.controller.Controller and tori.controller.RestController), what you need is just add the decorator tori.decorator.controller.custom_error() to the controller. For example,

@custom_error('error.html')
@renderer('web.views')
class HomeController(Controller):
    # Assuming something
    pass

References

For more information, please read

Read the Docs v: v2.1
Versions
latest
v2.1
v2.0
Downloads
PDF
HTML
Epub
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.