Dynamic template selection in Pyramid
If you usually use the view_config decorator to specify your rendering template so you can return a dictionary from your view, it may not be obvious how you can dynamically set the template, for example based on information in the request object.
I have a view set for the route '/content' which may return a list of available content, or given a specific URL return the details for the content associated with that URL. Making the URL part of the route URL pattern would not work well, so I'm passing it as a query parameter.
The question then is, how do I render the response of the view based on whether or not a specific URL has been requested. The answer lies in the custom_predicates
parameter of the view_config
decorator.
My custom predicate is simply a function that takes the context and request and returns whether or not a url
parameter has been passed:
def contains_url(context, request):
return bool(request.GET.get('url'))
Given my two templates, content_list.jinja2
, and content_detail.jinja2
, I've wired up my view like this:
@view_config(route_name='content',
renderer='templates/content_detail.jinja2',
custom_predicates=(contains_url,))
@view_config(route_name='content', renderer='templates/content_list.jinja2')
def content(request):
if request.GET.get('url'):
return lookup_content(request.GET['url'])
else:
return { 'content_list': list_content() }