[Bottle][bottle]’s [`@view` decorator][view] provides a simple way to designate a template to render an HTML page. Your view function just has to return a dictionary, and its contents can be accessed from the template using the `'{{ name }}’` syntax.
The `@view` decorator can also take keyword arguments. These are treated as default template variables – if the dictionary returned by your view function doesn’t have a key for one of the keyword arguments then the template will use the value passed into the decorator, like so:
from bottle import view
@view(‘default.html’, author=’David Buxton’)
def home():
return {‘title’: ‘Home page’}
That would render any instance of `'{{ author }}’` as `’David Buxton’`. And then you can have another view function that overrides the keywords by returning a different value in the dictionary:
from bottle import view
@view(‘default.html’, author=’David Buxton’)
def music():
return {‘title’: ‘Thalassocracy’, ‘author’: ‘Frank Black’}
And at that point I wonder what is the advantage of using keyword arguments with `@view`: you have to decorate each function separately, and if you want to override a keyword in your return dictionary then it would be easier not to specify the keyword in the first place.
Thus the real point of using keywords with the `@view` function is only apparent if you curry the `@view` decorator with keywords first so that you can re-use the curried decorator and avoid repeating yourself.
*Someday I will re-write the previous sentence. Until then, sorry.*
Instead of passing a default author each time as in the examples above, let’s make a new `@view` decorator (using Python’s [functools module][functools]) and then use that on each view function:
import functools
from bottle import view
view = functools.partial(view, author=’David Buxton’)
@view(‘default.html’)
def home():
return {‘title’: ‘Home page’}
@view(‘default.html’)
def music():
return {‘title’: ‘Thalassocracy’, ‘author’: ‘Frank Black’}
The new decorator means you get the default keyword arguments wherever you use `@view` while permitting any function to override those defaults in the dictionary it returns.
And if you wanted to get really lazy you could even pass in a template name when wrapping the decorator with `functools.partial`, however you would not be able to use your wrapped decorator to change the template name because it is a positional argument (like what [it explains here in the functools documentation][partial]). You would also have to call the decorator with no arguments like `’@defaultview()’`. So forget I mentioned it.
I’m not saying you are lazy.
[bottle]: http://bottle.paws.de/
[functools]: http://docs.python.org/library/functools.html
[partial]: http://docs.python.org/library/functools.html#functools.partial
[view]: http://bottle.paws.de/docs/0.8/api.html#bottle.view