Skip to content
alabid edited this page Aug 7, 2012 · 22 revisions

Controllers

According to the MVC specification which whirlwind is based upon, the Controller should handle the business logic. The Controller receives and responds to requests from the client. The user's requests for pages are routed to some subclass of the python class BaseRequest using the @route decorator.

Here's an example implementation of a controller that handles "static page" requests:

from whirlwind.core.request import BaseRequest                                                             
from whirlwind.db.mongo import Mongo                                                                       
from tornado.web import authenticated                                                                      
from whirlwind.view.decorators import route                                                                
                                                                                                        
@route('/')                                                                                                
class IndexHandler(BaseRequest):                                                                           
  def get(self):                                                                                         
    #template context variables go in here                                                             
    template_values = {}                                                                               
    
    # you can do some database manipulation here
    # or not do anything at all
   
    # render the template defined in application/views/site/index.html                                                                                             
    self.render_template('/site/index.html',**template_values)    

The above controller code just handles rendering the root page. This page can be in its own file: sites_controller.py.

We suggest that the Request Handlers (which are subclasses of BaseRequests) be categorized according to functionality. In other words, Request Handlers that handle static requests (that aren't related to any other indepth functions) can be placed together in sites_controller.py in the controllers folder. Handlers that handle requests to login and logout of the application can be placed in an accounts_controller.py. And so on...

In addition, each handler you define should have a 'get' or 'post' method or both. This conforms to the REST specification. For more information on the methods you can define in the subclass of BaseRequest, refer to the tornado RequestHandler documentation.

BaseRequest

The BaseRequest class is defined in the whirlwind python source. It's a subclass of the RequestHandler class that's part of the tornado python web server.

##Methods of BaseRequest

The BaseRequest class has several methods that are useful in rendering template file and template strings.

The methods explicated below can be invoked in a subclass of BaseRequest like this:

@route('/some/path')
class IndexHandler(BaseRequest):                                                                           
    def get(self):
        self.baseRequestMethod1(param1,param2)
    def post(self):
        self.baseRequestMethod2(param1, param2, param3)

@route('/some/other/path/([\w]+)')
class OtherPathHandler(BaseRequest):
    def get(self, get_param):
        self.baseRequestMethod3(params...)

where baseRequestMethodx is the method of the BaseRequest to invoke.

For more information on routing client request to controllers using the route decorator, refer to the decorators page.


Method : template_exists

Params : template_name - name of template

Returns : true if the template defined at template_name exists. Else returns false.

Example Use

if self.template_exists('/site/index.html'):
    print "yes! template exists there"

Method : render_string

Params :

  • template_name - name of template

  • **kwargs - dictionary of options to pass to view. For example, kwargs['me']="hi" would make the variable me available to the view.

Returns : String that's the result of pre-processing the template at template_name against the mako template syntax rules.

Alias : render_to_string

Example Use

str_to_render = self.render_to_string('/site/index.html')

# do some cool stuff with str_to_render

self.write(str_to_render)

Method : render_template

Params :

  • template_name - name of template to render

  • **kwargs - dictionary of options to pass to view. Same as in render_string

Return : None.

Note: This method is blocking and should be put at the bottom of the calling method.

Example Use

self.render_template('/site/index.html') # The last line of the BaseRequest handler

Method : get_nested_argument

Params : prefix - the prefix of the nested arguments to retrieve

Return : a dictionary of "inner" parameters. The keys will be the remaining part of the parameter keys (excluding the prefixes).

Example Use

 ## form  for inputing a person's data -->
 <form method="POST" action="/sendmama">
   <input type="text" name="person[first]" value="mama1" />
   <input type="text" name="person[second]" value="mama2" />
   <input type="text" name="person[third]"  value="mama3" />
   <input type="text" name="person[fourth]" value="mama4"/>
   <input type="text" name="person[fifth]" value="mama5" />
   <button type="submit">Send Mama</button>
 </form>

 --------------------------------------------------------------
 # then you could use get_nested_argument as follows:

 @route('/sendmama')
 class SendMamaHandler(BaseRequest):
     def post(self):
         print self.get_nested_argument("person")

 # prints out
 # {
 # "first" : "mama1", "second" : "mama2", "third" : "mama3",
 #  "fourth" : "mama4", "fifth" : "mama5"
 # }

Method : get_arguments_as_dict

Params : None

Return : a dictionary of all parameters sent over the network.


Method : get_argument

Params:

  • name (default value - None)

  • default (default value - None)

  • strip (default value - True)

Return : Returns the value that maps to name in the data sent over the network. Or else returns the default value.

Example Use

# first,
# assume json sent over network is: 
# "danielsage" : 18
print self.get_argument("danielsage")
# prints 18

# second,
# assume no json sent
print self.get_argument("danielsage", 17)
# prints 17
# since default value of "danielsage" is 17

Method : get_arguments

Params:

  • name (default value - None)

  • default (default value - None)

  • strip (default value - True)

Return : If param value is a list returns a list . Else if param value is not, returns the param's value. If no params are supplied, then returns same as self.get_arguments_as_dict.


Method : get_username

Params : None

Return : Returns the username of the current user


Method : write

Params :

  • chunk - what to write. Should preferably be html. To write

  • status (default - None) - status code for write action

Example Use

## write out the html "<html></html>"
self.write("<html></html")

Method : get_error_html

Params : status_code - status code of error html page to render

Return : Returns the html for an error page. There are pre-defined error pages in static/errors/ for the status codes 403, 404, 500, 503. For other status codes, it returns this template html:

<html>
   <title>%(code)d: %(message)s</title>    
   <body class='bodyErrorPage'>
      %(code)d: %(message)s
   </body>
</html>

## code - replaced with the status code
## message - replaced with the message corresponding to that status code

Use this method wisely!

Example Use

 # print the "Not Found" error html page
 print self.get_error_html(404)  

Note: Since BaseRequest is a subclass of the tornado RequestHandler methods, there are other methods that can be used on a BaseRequest. Check out the [documentation on the RequestHandler class] for more information(http://www.tornadoweb.org/documentation/web.html).

The methods get, post defined in a subclass of a BaseRequest to handle GET and POST requests to specific routes can be used with decorators such as @threaded, @authenticated, and @role_required. Check out the documentation on decorators here.

Clone this wiki locally