2

I'm trying to create multisite Wagtail project using included Django Sites framework. I could not find in Wagtail documentation how to serve templates and statics for each site individually. Could anyone help me with advise or a link to some tutorial? Thanks.

3 Answers3

1

In Wagtail the view logic lives on the page model. When a request is made Wagtail url resolver will call the page serve method. The Wagtail code form wagtail.core.models.Page looks like this:

def get_template(self, request, *args, **kwargs):
    if request.is_ajax():
        return self.ajax_template or self.template
    else:
        return self.template

def serve(self, request, *args, **kwargs):
    request.is_preview = getattr(request, 'is_preview', False)

    return TemplateResponse(
        request,
        self.get_template(request, *args, **kwargs),
        self.get_context(request, *args, **kwargs)
    )

To answer your question: You have to override get_template and add some logic to make the template name unique per site. This is untested code, but you get the idea:

class SomePage(Page):
    ...
    def get_template(self, request, *args, **kwargs):
        return request.site + super().get_template(request, *args, **kwargs)

Now the template name is prefixed with the site. So you only need to supply templates with the correct names.

allcaps
  • 10,945
  • 1
  • 33
  • 54
1

In Wagtail 2.10 this method is not valid anymore, request.site has been deprecated

Instead you can do that :

class SomePage(Page):
...
def get_template(self, request, *args, **kwargs):
    return Site.find_for_request(request).site_name + '/' + super().get_template(request, *args, **kwargs)

If you need to reference an ajax template you can also use this approach :

class SomePage(Page):
...

ajax_template = 'ajax_foo.html'
template = 'foo.html'

def get_template(self, request, *args, **kwargs):
    template = Site.find_for_request(request).site_name + '/' + self.template
    if request.is_ajax():
        template = Site.find_for_request(request).site_name + '/' + self.ajax_template
    return template
Theophile
  • 105
  • 1
  • 1
  • 8
0

Building on allcaps' answer, I created a simple proxy model that all of my Page models inherit from. Considering a page called BlogPage:

class SitePage(Page):
    def get_template(self, request):
        template_name = super().get_template(request)
        domain = request.get_host()

        if settings.DEBUG:
            if not domain.startswith('localhost'):
                domain = domain.split('.localhost')[0]

        return [
            domain + '/' + template_name,
            template_name,
        ]

    class Meta(Page.Meta):
        abstract = True


class BlogPage(SitePage):
    ...

Now I can have a templates/ folder that looks something like:

templates/
    domain1.com/
        blog_page.html
    domain2.com/
        blog_page.html
    domain3.com/
        blog_page.html

If you configure a Wagtail Site for each domain, this will apply the correct template based on the domain name.

A few extra features:

  • In debug mode, strips out localhost, so you could go to domain1.com.localhost:8000 and it would find the template for domain1.com
  • Returning a list of templates tries each in turn, so you can also have a default template that any site will use if a specific template isn't found.