# /test{.format} no longer seems to work...
config.add_route('test', '/test.{ext}', view='ms.views.test')
views.py:
from pyramid.response import Response
from pyramid.renderers import render
import json
def test(request):
extension = request.matchdict['ext']
variables = {'name' : 'blah', 'asd' : 'sdf'}
if extension == 'html':
output = render('mypackage:templates/blah.pt', variables, request=request)
if extension == 'json':
output = json.dumps(variables)
return Response(output)
Is there an easier way to do this? With Pylons, it was a simple:
def test(self, format='html'):
c.variables = {'a' : '1', 'b' : '2'}
if format == 'json':
return json.dumps(c.variables)
return render('/templates/blah.html')
I suspect I'm approaching this the wrong way...?
I think, the better way is to add the same view twice with difference renderers. Suppose we have the following view:
def my_view(request):
return {"message": "Hello, world!"}
Now in our configuration we can add the same view twice:
from pyramid.config import Configurator
config = Configurator()
config.add_route('test', '/test', my_view, renderer="templates/my_template.mako")
config.add_route('test', '/test', my_view, renderer="json", xhr=True)
What we have now:
my_view
will render template "templates/my_template.mako"
with returned dict provided as context if we will point our browser to url /test
.my_view
will be called again, but now returned dict will be encoded as JSON and transmitted back to caller (please read docs about checking if request was done via XHR).The same idea we can use for defining different routes but with the same view attached to them:
from pyramid.config import Configurator
config = Configurator()
config.add_route('test', '/test', my_view, renderer="templates/my_template.mako")
config.add_route('test_json', '/test.json', my_view, renderer="json")
Now /test
will trigger template rendering, but /test.json
will return just JSON encoded string.
You can go further and make dispatching to the right renderer via accept
argument of add_router
method:
from pyramid.config import Configurator
config = Configurator()
config.add_route('test', '/test', my_view, renderer="templates/my_template.mako")
config.add_route('test', '/test', my_view, renderer="json", accept="application/json")
If request comes with header Accept
set to application/json
value JSON will be returned, otherwise you got rendered template.
Note, this will work only if you have predefined set of data formats in which you want to encode responses from your views, but it's the usual case. In case you need dynamical dispatching you can decorate your views with decorate
argument of add_route
which will choose the right renderer with your rules.