Views¶
Views provide the “V” in MVC. Controllers use views to render responses to requests. Ferris provides three different built-in views for rendering HTML from templates, JSON from a dictionary, and JSON from a protorpc Message. Alternatively, you can use Response Handlers to generate responses or you may generate responses manually.
Context¶
In order to provide data to the view, the controller must provide a view context. The context is a simple Python dictionary from which you can pass data from the controller to the view.
Inside of a controller, use self.context:
def action(self):
self.context['my_data'] = "Hello!"
These are now available within the view. For example, in the template view:
{{my_data}}
You can pass any Python object into your view via the view context.
Switching Views¶
The template view is used by default but you can easily switch the view. You can configure it for all actions using Meta.View:
class MyController(Controller):
class Meta:
View = 'json'
Or you can switch dynamically using change_view():
def action(self):
self.meta.change_view('json')
Template View¶
The template view provides glue between controllers and the templating engine. It exposes the view context directly to jinja2. For more details, see Templates.
JSON View¶
The JSON view can serialize a dictionary using the standard Python JSON library. For example:
def action(self):
self.meta.change_view('json')
self.context['data'] = {
'hello': 'world'
}
This will return the following when called:
{"hello": "world"}
You must set the data key in the view context for the JSON view to work.
Message View¶
The Messages view will serialize a protorpc Message as JSON. For example:
from ferris import messages
class HelloMessage(messages.Message):
hello = messages.StringField(0)
...
def action(self):
self.meta.change_view('message')
self.context['data'] = HelloMessage(hello="world")
This will return the following when called:
{"hello": "world"}
You must set the data key in the view context for the messages view to work.
Custom Views¶
Creating a custom view is fairly straightforward. Simply subclass View and implement the render() method:
from ferris.core.views import View
class CustomView(View):
def render(self, *args, **kwargs):
self.controller.events.before_render(controller=self.controller)
self.controller.response.unicode_body = u"Hello, world!"
self.controller.events.after_render(controller=self.controller)
return self.controller.response
Then to use it just use either Meta.View or meta.change_view:
self.meta.change_view('custom')
Events¶
Views have events similar to controller events, but are handled seperately. These are only used by the template view although you may utilize them for you own custom views as well.
View events are available for Controllers via self.meta.view.events. These are not preserved when switching views.
View events are available in template views via this.events.
For example, if you wanted to inject scripts into the template using components:
#---- Component:
class ScriptComponent(object):
def __init__(self, controller):
self.controller.meta.view.events.layout_scripts += self.layout_scripts
def layout_scripts(self):
return '<script type="text/javascript" src="/js/myscript.js"></script>'
#---- Controller:
class MyController(Controller):
class Meta:
components = (ScriptComponent,)
#---- Layout:
{{this.events.layout_scripts()}}