View Classes¶
View classes take in data that the model returns, and returns data that is viewable. For instance, if the model returns a simple dictionary:
{‘x’: 3, ‘y’: 10, ‘result’: 30}
The the view’s job is to take this data and return a visual representation, such as:
3 * 10 == 30
or:
<!DOCTYPE html>
<html>
<body>
<p>3 * 10 == 30</p>
</body>
</html>
Creating View Classes¶
All view classes must descent from giotto.views.BaseView
.
Each class needs to implement at least one mimetype method:
from giotto.views import BaseView
class MyView(BaseView):
@renders('text/plain')
def plaintext(self, result):
return "%(x)s * %(y)s == %(result)s" % result
Each method can be named whatever you want, and must be decorated with the @renders
decorator.
The renders
decorator takes multiple string arguments representing the mimetype that method renders.
When creating views, make sure there is no ‘impedance mismatch’ between the data that the model returns,
and the data the view is written to take in.
For instance, the above mimetype method is designed to display a dictionary with three keys (x
, y
, and result
).
If the model was changed to return a list, this view method will crash.
Return values¶
Each mimetype render method should return either a string:
return "return a string"
or a dictionary with body and mimetype tags:
return {'body': "this is whats returned, 'mimetype': 'text/plain'}
If the method returns just a string, the controller wil treat the content as the
first mimetype passed into the renders
decorator::
@renders('text/plain', 'text/html', 'text/x-cmd')
def multi_render(self, result):
return "text"
This content will be treated as text/plain
by the controller.
Persisting data¶
Sometimes, instead of mearly displaying model-generated values to the user,
you want to persist that value.
An example of this is saving session data to a cookie instead of displaying it in the HTML.
To do this, add the data to the persist
key in the dictionary the render function returns:
{'body': "this is whats returned, 'mimetype': 'text/plain', 'persist': {'cookie_name': 'cookie value'}}
BasicView¶
There is a view class called BasicView
that was created to be a quick and dirty way to view most any data.
While developing your application, it is a good idea to use BaseView
until you have settled on a consistent data type that your model returns. Also you should inherit all custom views from BasicView
for convenience.
Overriding Renderers¶
In the manifest file, you can override a renderer by passing in the renderer function as a keyword argument to the view class:
manifest = Manifest({
'multiply': Program(
model=[multiply],
view=BasicView(
html=lambda m: str(m)
),
),
})
This program will output a string representation of the model output when viewed in an HTML context.
When viewed in a json context, the output will be the json renderer defined in BasicView
.
Renderer functions¶
Renderer functions take two arguments, the first argument is the object that the model returns, and the second argument is the errors that may have came from a previous invocation. The second argument is optional. Renderer functions can be either defined as a method on the view class, or passed in to the view class constructor.