From 4dba03493300f43c12fdfd2368de6bc7b2fd2b40 Mon Sep 17 00:00:00 2001 From: srijanid <srijanidas06@gmail.com> Date: Fri, 31 Jan 2025 23:17:46 +0530 Subject: [PATCH 1/2] improving 404 page --- djangoproject/templates/404.html | 52 ++++++++++++++++++++++++-------- docs/templatetags/docs.py | 38 ++++++++++++++++++----- 2 files changed, 70 insertions(+), 20 deletions(-) diff --git a/djangoproject/templates/404.html b/djangoproject/templates/404.html index 885c594a3b..10d2eadecb 100644 --- a/djangoproject/templates/404.html +++ b/djangoproject/templates/404.html @@ -1,23 +1,51 @@ {% extends 'base_error.html' %} {% load i18n %} +{% load custom_tags %} {% block title %}{% translate "Page not found" %}{% endblock %} -{% block header %}<h1>404</h1>{% endblock %} +{% block header %} + <h1 class="error-title">404 - Page Not Found</h1> + <p class="error-subtitle"> + {% translate "Oops! The page you’re looking for doesn’t exist." %} + </p> +{% endblock %} {% block content %} - <h2>{% translate "Page not found" %}</h2> + <div class="error-container"> + <h2>{% translate "We couldn’t find the page:" %}</h2> + <p class="broken-url">"<strong>{{ broken_path }}</strong>"</p> + + <p> + {% blocktranslate trimmed %} + Looks like you followed a bad link. If you think it's our fault, please + <a href="https://code.djangoproject.com/">let us know</a>. + {% endblocktranslate %} + </p> - <p> - {% blocktranslate trimmed %} - Looks like you followed a bad link. If you think it's our fault, please - <a href="https://code.djangoproject.com/">let us know</a>. - {% endblocktranslate %}</p> + <!-- Search Form --> + <div class="search-container"> + <form method="get" action="{% url 'doc_search' %}"> + {{ form.as_p }} + <button type="submit" class="search-button">{% translate "Search Docs" %}</button> + </form> + </div> - {% url 'homepage' as homepage_url %} - <p> - {% blocktranslate trimmed %} - Here's a link to the <a href="{{ homepage_url }}">homepage</a>. You know, just in case. - {% endblocktranslate %}</p> + <!-- Suggested Closest Matches --> + {% if suggestions %} + <h3>{% translate "Did you mean?" %}</h3> + <ul class="suggestion-list"> + {% for suggestion in suggestions %} + <li><a href="{{ suggestion }}">{{ suggestion }}</a></li> + {% endfor %} + </ul> + {% endif %} + {% url 'homepage' as homepage_url %} + <p> + {% blocktranslate trimmed %} + Here's a link to the <a href="{{ homepage_url }}">homepage</a>. You know, just in case. + {% endblocktranslate %} + </p> + </div> {% endblock %} diff --git a/docs/templatetags/docs.py b/docs/templatetags/docs.py index 194a77e7f2..7732542dc0 100644 --- a/docs/templatetags/docs.py +++ b/docs/templatetags/docs.py @@ -1,28 +1,50 @@ from django import template from django.utils.safestring import mark_safe -from django.utils.version import get_version_tuple +from django.utils.version import get_version_tuple # from pygments import highlight from pygments.formatters.html import HtmlFormatter from pygments.lexers import get_lexer_by_name - +import difflib +from django.shortcuts import get_object_or_404 +from django.urls import reverse +from django.http import Http404 +from django.conf import settings from ..forms import DocSearchForm from ..models import DocumentRelease from ..utils import get_doc_path, get_doc_root register = template.Library() +# List of existing docs URLs for similarity matching +EXISTING_DOCS_URLS = [ + "/en/4.2/ref/databases/", + "/en/4.2/ref/models/", + "/en/4.2/topics/db/", + "/en/4.2/howto/custom-model-fields/", + "/en/4.2/ref/settings/", + # Add more known URLs as needed +] + +def get_suggestions(broken_url): + """Finds close matches for the broken URL using difflib.""" + return difflib.get_close_matches(broken_url, EXISTING_DOCS_URLS, n=3, cutoff=0.6) @register.inclusion_tag("docs/search_form.html", takes_context=True) def search_form(context): request = context["request"] - release = DocumentRelease.objects.get_by_version_and_lang( - context["version"], - context["lang"], - ) + version = context.get("version", context.get("DJANGO_VERSION")) + lang = context.get("lang", context.get("LANGUAGE_CODE")) + + release = get_object_or_404(DocumentRelease, version=version, lang=lang) + broken_path = request.path.replace(f"/{lang}/{version}/", "", 1) + suggestions = get_suggestions(f"/{broken_path}") + return { "form": DocSearchForm(request.GET, release=release), - "version": context["version"], - "lang": context["lang"], + "version": version, + "lang": lang, + "suggestions": suggestions, + "broken_path": broken_path, } From e64f785503ad9c1725d64ac99e878041d9f4a1b2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 31 Jan 2025 17:53:09 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- docs/templatetags/docs.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/templatetags/docs.py b/docs/templatetags/docs.py index 7732542dc0..cdd5e597ee 100644 --- a/docs/templatetags/docs.py +++ b/docs/templatetags/docs.py @@ -1,14 +1,16 @@ +import difflib + from django import template +from django.conf import settings +from django.http import Http404 +from django.shortcuts import get_object_or_404 +from django.urls import reverse from django.utils.safestring import mark_safe -from django.utils.version import get_version_tuple # +from django.utils.version import get_version_tuple from pygments import highlight from pygments.formatters.html import HtmlFormatter from pygments.lexers import get_lexer_by_name -import difflib -from django.shortcuts import get_object_or_404 -from django.urls import reverse -from django.http import Http404 -from django.conf import settings + from ..forms import DocSearchForm from ..models import DocumentRelease from ..utils import get_doc_path, get_doc_root @@ -25,10 +27,12 @@ # Add more known URLs as needed ] + def get_suggestions(broken_url): """Finds close matches for the broken URL using difflib.""" return difflib.get_close_matches(broken_url, EXISTING_DOCS_URLS, n=3, cutoff=0.6) + @register.inclusion_tag("docs/search_form.html", takes_context=True) def search_form(context): request = context["request"]