diff --git a/static/src/scss/_404.scss b/static/src/scss/_404.scss new file mode 100644 index 0000000..ffb880c --- /dev/null +++ b/static/src/scss/_404.scss @@ -0,0 +1,43 @@ +body.page-404 { + main { + height: 100%; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + margin: 0; + color: $white; + } + + .content-wrapper { + position: absolute; + text-align: center; + background-color: color.adjust($dark, $alpha: -0.2); + border-radius: $input-radius; + padding: 2rem; + + h1 { + font-size: 5rem; + } + + p { + font-size: 110%; + } + + a:hover { + color: $grey-lighter; + } + } + + marquee { + background-repeat: no-repeat; + background-size: cover; + background-position: center; + width: 100%; + height: 100%; + + &.outer { + font-size: 5rem; + } + } +} diff --git a/static/src/scss/base.scss b/static/src/scss/base.scss index 0c39012..06e07b2 100644 --- a/static/src/scss/base.scss +++ b/static/src/scss/base.scss @@ -16,6 +16,7 @@ @import "shareon"; @import "search"; @import "spotify"; +@import "404"; html, body { diff --git a/website/common/templates/404.html b/website/common/templates/404.html index d31e54c..da9ae2a 100644 --- a/website/common/templates/404.html +++ b/website/common/templates/404.html @@ -1,11 +1,21 @@ {% extends "base.html" %} +{% load static wagtailcore_tags wagtailimages_tags %} + +{% block body_class %}page-404{% endblock %} + {% block title %}Page not found{% endblock %} -{% block body_class %}template-404{% endblock %} +{% block main_content %} + + + 🤷 + + -{% block content %} -

Page not found

- -

Sorry, this page could not be found.

+
+

There's nothing here!

+

The page you are looking for could not be found.

+

Go home

+
{% endblock %} diff --git a/website/common/tests/test_views.py b/website/common/tests/test_views.py new file mode 100644 index 0000000..ede6b6c --- /dev/null +++ b/website/common/tests/test_views.py @@ -0,0 +1,14 @@ +from django.test import TestCase +from django.urls import reverse + + +class Error404PageTestCase(TestCase): + url = reverse("404") + + def test_accessible(self) -> None: + response = self.client.get(self.url) + self.assertEqual(response.status_code, 404) + + def test_queries(self) -> None: + with self.assertNumQueries(10): + self.client.get(self.url) diff --git a/website/common/views.py b/website/common/views.py new file mode 100644 index 0000000..9541896 --- /dev/null +++ b/website/common/views.py @@ -0,0 +1,23 @@ +from typing import Any + +from django.http.response import HttpResponse +from django.views.defaults import ERROR_404_TEMPLATE_NAME +from django.views.generic import TemplateView + +from website.home.models import HomePage + + +class Error404View(TemplateView): + template_name = ERROR_404_TEMPLATE_NAME + + def render_to_response(self, context: dict, **response_kwargs: Any) -> HttpResponse: + response_kwargs["status"] = 404 + return super().render_to_response(context, **response_kwargs) + + def get_context_data(self, **kwargs: dict) -> dict: + context = super().get_context_data(**kwargs) + context["homepage"] = HomePage.objects.live().get() + return context + + +page_not_found = Error404View.as_view() diff --git a/website/urls.py b/website/urls.py index 89eeae5..bedf18b 100644 --- a/website/urls.py +++ b/website/urls.py @@ -6,6 +6,8 @@ from wagtail.contrib.sitemaps.views import sitemap from wagtail.documents import urls as wagtaildocs_urls from wagtail.images.views.serve import ServeView +from website.common.views import page_not_found + urlpatterns = [ path("admin/", include(wagtailadmin_urls)), path("documents/", include(wagtaildocs_urls)), @@ -19,9 +21,14 @@ urlpatterns = [ name="wagtailimages_serve", ), path("sitemap.xml", sitemap), + path("404/", page_not_found, name="404"), ] +if not settings.DEBUG: + handler404 = "website.common.views.page_not_found" + + if settings.DEBUG: from django.conf.urls.static import static