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
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.
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:
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.
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.
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).
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>
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
For more information, please read