Last Updated: February 25, 2016
·
801
· scott2b

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() }