Merge pull request 'Provide custom error pages' (#114) from 20-error-pages into main
Reviewed-on: #114
This commit is contained in:
commit
6e88969677
9 changed files with 97 additions and 1 deletions
9
src/servala/frontend/templates/403.html
Normal file
9
src/servala/frontend/templates/403.html
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{% extends "error_base.html" %}
|
||||||
|
|
||||||
|
{% block title %}403 - Access Forbidden{% endblock title %}
|
||||||
|
|
||||||
|
{% block error_alt %}Access Forbidden{% endblock error_alt %}
|
||||||
|
|
||||||
|
{% block error_title %}Access Forbidden{% endblock error_title %}
|
||||||
|
|
||||||
|
{% block error_message %}You are not authorized to access this page.{% endblock error_message %}
|
9
src/servala/frontend/templates/404.html
Normal file
9
src/servala/frontend/templates/404.html
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{% extends "error_base.html" %}
|
||||||
|
|
||||||
|
{% block title %}404 - Page Not Found{% endblock title %}
|
||||||
|
|
||||||
|
{% block error_alt %}Not Found{% endblock error_alt %}
|
||||||
|
|
||||||
|
{% block error_title %}Page Not Found{% endblock error_title %}
|
||||||
|
|
||||||
|
{% block error_message %}The page you are looking for could not be found.{% endblock error_message %}
|
9
src/servala/frontend/templates/500.html
Normal file
9
src/servala/frontend/templates/500.html
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{% extends "error_base.html" %}
|
||||||
|
|
||||||
|
{% block title %}500 - Server Error{% endblock title %}
|
||||||
|
|
||||||
|
{% block error_alt %}Server Error{% endblock error_alt %}
|
||||||
|
|
||||||
|
{% block error_title %}Server Error{% endblock error_title %}
|
||||||
|
|
||||||
|
{% block error_message %}The website is currently unavailable. Please try again later or contact support.{% endblock error_message %}
|
33
src/servala/frontend/templates/error_base.html
Normal file
33
src/servala/frontend/templates/error_base.html
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{% load static %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{% block title %}Error{% endblock title %} - Servala</title>
|
||||||
|
<link rel="shortcut icon"
|
||||||
|
href="data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2033%2034'%20fill-rule='evenodd'%20stroke-linejoin='round'%20stroke-miterlimit='2'%20xmlns:v='https://vecta.io/nano'%3e%3cpath%20d='M3%2027.472c0%204.409%206.18%205.552%2013.5%205.552%207.281%200%2013.5-1.103%2013.5-5.513s-6.179-5.552-13.5-5.552c-7.281%200-13.5%201.103-13.5%205.513z'%20fill='%23435ebe'%20fill-rule='nonzero'/%3e%3ccircle%20cx='16.5'%20cy='8.8'%20r='8.8'%20fill='%2341bbdd'/%3e%3c/svg%3e"
|
||||||
|
type="image/x-icon">
|
||||||
|
<link rel="stylesheet" href="{% static 'mazer/compiled/css/app.css' %}">
|
||||||
|
<link rel="stylesheet" href="{% static 'mazer/compiled/css/error.css' %}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script src="{% static 'mazer/static/js/initTheme.js' %}"></script>
|
||||||
|
<div id="error">
|
||||||
|
<div class="error-page container">
|
||||||
|
<div class="col-md-8 col-12 offset-md-2">
|
||||||
|
<div class="text-center">
|
||||||
|
<img class="img-error"
|
||||||
|
src="{% static 'img/sir-vala-notext.png' %}"
|
||||||
|
alt="Sir Vala - {% block error_alt %}Error{% endblock error_alt %}"
|
||||||
|
style="max-width: 300px;
|
||||||
|
margin-bottom: 2rem">
|
||||||
|
<h1 class="error-title">{% block error_title %}Error{% endblock error_title %}</h1>
|
||||||
|
<p class="fs-5 text-gray-600">{% block error_message %}An error occurred.{% endblock error_message %}</p>
|
||||||
|
<a href="/" class="btn btn-lg btn-outline-primary mt-3">Go Home</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1,3 +1,4 @@
|
||||||
|
from django.conf import settings
|
||||||
from django.urls import include, path
|
from django.urls import include, path
|
||||||
from django.views.generic import RedirectView
|
from django.views.generic import RedirectView
|
||||||
|
|
||||||
|
@ -64,4 +65,18 @@ urlpatterns = [
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
path("", RedirectView.as_view(pattern_name="frontend:profile"), name="index"),
|
path("", RedirectView.as_view(pattern_name="frontend:profile"), name="index"),
|
||||||
|
# Error page URLs available in all environments
|
||||||
|
path(
|
||||||
|
"error404/",
|
||||||
|
views.custom_404,
|
||||||
|
{"exception": Exception("Test 404")},
|
||||||
|
name="error_404",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"error403/",
|
||||||
|
views.custom_403,
|
||||||
|
{"exception": Exception("Test 403")},
|
||||||
|
name="error_403",
|
||||||
|
),
|
||||||
|
path("error500/", views.custom_500, name="error_500"),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from .auth import LogoutView
|
from .auth import LogoutView
|
||||||
from .generic import IndexView, ProfileView
|
from .generic import IndexView, ProfileView, custom_403, custom_404, custom_500
|
||||||
from .organization import (
|
from .organization import (
|
||||||
OrganizationCreateView,
|
OrganizationCreateView,
|
||||||
OrganizationDashboardView,
|
OrganizationDashboardView,
|
||||||
|
@ -29,4 +29,7 @@ __all__ = [
|
||||||
"ServiceListView",
|
"ServiceListView",
|
||||||
"ServiceOfferingDetailView",
|
"ServiceOfferingDetailView",
|
||||||
"ProfileView",
|
"ProfileView",
|
||||||
|
"custom_404",
|
||||||
|
"custom_403",
|
||||||
|
"custom_500",
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.shortcuts import render
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.views.generic import TemplateView
|
from django.views.generic import TemplateView
|
||||||
|
@ -42,3 +43,15 @@ class ProfileView(HtmxUpdateView):
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
form.save()
|
form.save()
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
|
def custom_404(request, exception):
|
||||||
|
return render(request, "404.html", status=404)
|
||||||
|
|
||||||
|
|
||||||
|
def custom_403(request, exception):
|
||||||
|
return render(request, "403.html", status=403)
|
||||||
|
|
||||||
|
|
||||||
|
def custom_500(request):
|
||||||
|
return render(request, "500.html", status=500)
|
||||||
|
|
BIN
src/servala/static/img/sir-vala-notext.png
Normal file
BIN
src/servala/static/img/sir-vala-notext.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 92 KiB |
|
@ -26,3 +26,8 @@ urlpatterns = [
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
|
||||||
|
# Custom error handlers
|
||||||
|
handler404 = "servala.frontend.views.custom_404"
|
||||||
|
handler403 = "servala.frontend.views.custom_403"
|
||||||
|
handler500 = "servala.frontend.views.custom_500"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue