massive_dynamic
massive_dynamic

Reputation: 346

Dynamic wagtail page

Can anyone tell me about dynamic pages in wagtail?

My use case is as following:

  1. I have a number of objects (images) on the main page

  2. When I click on image I'd like to be redirected to a page about this object (I can get detailed info about object via ajax)

  3. But I don't want to create pages for each object. I would rather make smth like this: mysite.com/images?image_id=254 (with a model and template for such page)

Can it be done? If so please tell me where to look in documentation xx

Upvotes: 2

Views: 2025

Answers (1)

gasman
gasman

Reputation: 25227

This sounds like an ideal use for RoutablePageMixin, which allows you to define multiple views for one page, using Django-like URL patterns. In this case, you could define two views, one for the main page (at the URL /images/) and one for a specific object (at the URL /images/123/):

from django.shortcuts import get_object_or_404, render
from wagtail.contrib.routable_page.models import RoutablePageMixin, route

class ProductListingPage(RoutablePageMixin, Page):

    @route(r'^$')
    def index_view(self, request):
        # render the index view
        return render(request, 'products/index.html', {
            'page': self,
        })

    @route(r'^(\d+)/$')
    def product_view(self, request, product_id):
        # render the view for a single item
        product = get_object_or_404(Product, id=product_id)
        return render(request, 'products/product.html', {
            'product': product,
            'page': self,
        })

If you want to go lower-level, you can try overriding the page's serve method - this is how RoutablePageMixin works internally. Overriding serve is sufficient to support URLs like mysite.com/images?image_id=254 :

class ProductListingPage(Page):
    def serve(self, request):
        product_id = request.GET.get('image_id', None)
        if product_id is None:
            return render(request, 'products/index.html', {
                'page': self,
            })
        else:
            product = get_object_or_404(Product, id=product_id)
            return render(request, 'products/product.html', {
                'product': product,
                'page': self,
            })

To get nicer URLs of the form mysite.com/images/123/, you could override the route method as well.

Upvotes: 6

Related Questions