Since web2py 1.63 we made it very easy to return data in formats other then HTML, upon request. For example, consider the following action in controller "default" on app "app"
def count():
session.counter=(session.counter or 0)+1
return dict(counter=session.counter, now=request.now)
(this action returns a counter that is increase when the visitor reload the page, and the timestamp of the current page request)
Normally this page would be requested via
http://127.0.0.1:8000/app/default/count
Since web2py 1.63 the same page can also be requested as
http://127.0.0.1:8000/app/default/count.html
http://127.0.0.1:8000/app/default/count.xml
http://127.0.0.1:8000/app/default/count.json
And the dictionary will be rendered in HTML, XML and JSON respectively.
Other extensions can be easily defined by the user. When the .xxx extension in called web2py looks for a template file called default/count.xxx and if it does not find it, it looks for a template generic.xxx. The files generic.html, generic.xml, generic.json and generic.rss (described below) are provided with the latest scaffolding app.
There is nothing to do to enable this in new web2py app. To use it in old/existing web2py app just copy the generic.* files from the scaffolding app.
Here is sample generic.pickle that can return the dict pickled
{{
import cPickle
response.write(cPickle.dumps(response._vars),escape=False)
}}
which allows visitors to call
http://127.0.0.1:8000/app/default/count.pickle
To generate an RSS feed using this method, web2py provides a generic.rss but it only works if the action returns a dictionary containing a "title", "link", "description", and "items" where items is a list of dictionaries each with a "title", "link", "description". For example
def feed():
return dict(title="my feed",
link="http://feed.example.com",
description="my first feed",
items=[
dict(title="my feed",
link="http://feed.example.com",
description="my first feed")
])
This action can be accessed as
http://127.0.0.1:8000/app/default/feed
http://127.0.0.1:8000/app/default/feed.html
http://127.0.0.1:8000/app/default/feed.xml
http://127.0.0.1:8000/app/default/feed.json
but also as
http://127.0.0.1:8000/app/default/feed.rss
Yes, of course it works on the Google App Engine too.
Yes, they are bytecompiled when you press the "compile" button in the admin interface
Yes, you can cache them if you modify the action:
@cache(request.env.path_info,time_expire=100,cache_model=cache.ram)
def count():
session.counter=(session.counter or 0)+1
d=dict(counter=session.counter, now=request.now)
return response.render('default/count.'+request.extension,d)