I have 3 different product page layouts that I would like to display dependent on the information available about the products. Using traversal I have a class called ProductFinder
that grabs all the information. For example the user goes to domain/green/small and ProductFinder
will list all products from my DB that are green and small. This list is self.products in the ProductFinder
class. In my __init__.py
I have added the line:
config.add_view('app.views.products', name='')
In products.py I have:
from pyramid.view import view_config
@view_config(context='app.models.ProductFinder', renderer='productpage.mako')
def products(context, request):
return dict(page=context)
Based on what's in context.products though I'd like to render a different mako. In Pylons I would have done something like:
def products(context, request):
if len(context.products) == 1:
return render("oneproduct.mako")
elif len(context.product) == 2:
return render("twoproducts.mako")
So how can I render a different template based on the contents of my context?
I will start off by saying this sort of seems like something you want to take care of in your template.
However, you can influence which renderer is used as part of the view lookup in just about any way you want to. As you might already know you can use the same view handler for multiple views, you simply need to help Pyramid figure out which one to use.
For example:
from pyramid.view import view_config
def ProductLengthPredicate(length):
def check_length(context, request):
return len(context.products) == length
return check_length
@view_config(context='app.models.ProductFinder', renderer='oneproduct.mako',
custom_predicates=(ProductLengthPredicate(1),))
@view_config(context='app.models.ProductFinder', renderer='twoproducts.mako',
custom_predicates=(ProductLengthPredicate(2),))
@view_config(context='app.models.ProductFinder', renderer='manyproducts.mako')
def products(context, request):
return dict(page=context)
NB. Some people might be more interested in the render_to_response
approach here because then they will not be relying on custom_predicates
. But it is of course up to you!
@view_config(context='app.models.ProductFinder', renderer='manyproducts.mako')
def products(context, request)
opts = dict(page=context)
if len(context.products) == 1:
return render_to_response('oneproduct.mako', opts, request)
if len(context.products) == 2:
return render_to_response('twoproducts.mako', opts, request)
return opts
This works because Pyramid will ignore the renderers if your view returns a Response()
which is exactly what render_to_response
does.
I'm not sure if it's the good way to go, but you could probably use request.override_renderer = 'oneproduct.mako'
.
If it is just a different way of displaying your products depending on the quantity, you should do the decision in the template.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With