Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having a 404 for each site in a Wagtail multisite setup

Tags:

I'm trying to get two different Wagtail sites to have their own 404 pages, but there does not appear to be a way to specify which page to use as 404 page in a "site" config in the wagtail "settings" => "sites" section, and I can't seem to get the correct 404 to be loaded when I put them into the app directories involved:

codebase/
  ./__init__.py
  ./manage.py
  ./apps/
     ./settings.py
     ./urls.py
     ...
     ./django-app-1/
     ./django-app-2/
     ./templates/
        ./404.html
     ./mainsite/
        ./migrations/
        ./static/
        ./templates/
           ./mainsite/
           ./404.html (this 404 always gets used)
     ./spinoff/
        ./migrations/
        ./static/
        ./templates/
           ./spinoff/
           ./404.html (this file never gets used)

So in INSTALLED_APPS we have:

INSTALLED_APPS = [
  ...django apps...
  ...wagtail apps...

  'apps.mainsite',
  'apps.spinoff',
]

In this, the main site has the vast bulk of all the page types, and the spinoff site, which runs on a different domain, uses those page types by importing them from apps.mainsite.

In Wagtail we have two pages that work as root: a Homepage that is a mainsite Page type, and a Spinoff Homepage that is a spinof Page type that inherits from the mainsite's page type.

In the sites settings, we have one site entry that points to mainsite.com, with the main Homepage set as Root, and another site entry that points to spinoff.com, with the spinoff homepage set as root.

For both of these sites, an non-existent url request leads to the main site's 404.html getting used, so the question is: how do we make non-existent urls on the spinoff domain resolve to the spinoff's 404.html instead?

like image 994
Mike 'Pomax' Kamermans Avatar asked Jun 04 '19 18:06

Mike 'Pomax' Kamermans


1 Answers

Since Wagtail is built on Django, you can customize the error view. Wagtail's core.view.serve calls core.models.page.route, and if the page route isn't found, then it raises Http404. Therefore, in urls.py you would put:

from yourapp.views import custom404_view

handler404 = 'yourapp.views.custom404_view'

And in views.py:

from django.http import HttpResponseNotFound

def custom404_view(request, exception):       
    return HttpResponseNotFound('<h1>{}</h1>'.format(request.site))

What I've shown above returns the Wagtail site to illustrate that the site is available in the view, so in your case, just return your HTML conditionally based upon the site.

like image 109
Dan Swain Avatar answered Oct 03 '22 10:10

Dan Swain