From 5241bddd52471056a8ab40afcaf19a34148d4fbc Mon Sep 17 00:00:00 2001 From: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> Date: Fri, 17 Oct 2025 18:54:09 +0200 Subject: [PATCH 1/3] Added DEFAULT_LANGUAGE_CODE setting. --- aggregator/tests.py | 2 +- blog/models.py | 2 +- djangoproject/tests.py | 5 ++++- docs/management/commands/update_docs.py | 6 +++-- docs/models.py | 8 ++++--- docs/templatetags/docs.py | 3 ++- docs/tests/test_models.py | 29 +++++++++++++++---------- docs/tests/test_templates.py | 17 +++++++++++---- docs/tests/test_views.py | 10 +++++++-- docs/views_debug.py | 5 ++++- releases/templatetags/release_notes.py | 3 ++- 11 files changed, 62 insertions(+), 28 deletions(-) diff --git a/aggregator/tests.py b/aggregator/tests.py index 9f705be184..2c28d57812 100644 --- a/aggregator/tests.py +++ b/aggregator/tests.py @@ -26,7 +26,7 @@ def setUp(self, mocker): ) DocumentRelease.objects.update_or_create( release=release, - lang="en", + lang=settings.DEFAULT_LANGUAGE_CODE, defaults={"is_default": True}, ) diff --git a/blog/models.py b/blog/models.py index a5e629ad50..f27cffd6cd 100644 --- a/blog/models.py +++ b/blog/models.py @@ -211,7 +211,7 @@ def invalidate_cached_entry(self): ) is_secure = url.scheme == "https" request = rf.get(url.path, secure=is_secure) - request.LANGUAGE_CODE = "en" + request.LANGUAGE_CODE = settings.DEFAULT_LANGUAGE_CODE cache = caches[settings.CACHE_MIDDLEWARE_ALIAS] cache_key = _generate_cache_header_key( settings.CACHE_MIDDLEWARE_KEY_PREFIX, request diff --git a/djangoproject/tests.py b/djangoproject/tests.py index 127332bfdc..61cc3613e8 100644 --- a/djangoproject/tests.py +++ b/djangoproject/tests.py @@ -1,6 +1,7 @@ from http import HTTPStatus from io import StringIO +from django.conf import settings from django.core.management import call_command from django.test import TestCase from django.urls import NoReverseMatch, get_resolver @@ -98,7 +99,9 @@ class ExcludeHostsLocaleMiddlewareTests(TestCase): @classmethod def setUpTestData(cls): r2 = Release.objects.create(version="2.0") - DocumentRelease.objects.create(lang="en", release=r2, is_default=True) + DocumentRelease.objects.create( + lang=settings.DEFAULT_LANGUAGE_CODE, release=r2, is_default=True + ) def test_docs_host_excluded(self): """We get no Content-Language or Vary headers when docs host is excluded""" diff --git a/docs/management/commands/update_docs.py b/docs/management/commands/update_docs.py index d1f3df0486..29e251312b 100644 --- a/docs/management/commands/update_docs.py +++ b/docs/management/commands/update_docs.py @@ -79,7 +79,9 @@ def _get_doc_releases(self, versions, options): # Skip translated non-stable versions to avoid a crash: # https://github.com/django/djangoproject.com/issues/627 - queryset = queryset.filter(Q(lang="en") | Q(release=default_docs_version)) + queryset = queryset.filter( + Q(lang=settings.DEFAULT_LANGUAGE_CODE) | Q(release=default_docs_version) + ) if options["language"]: queryset = queryset.filter(lang=options["language"]) @@ -161,7 +163,7 @@ def build_doc_release(self, release, force=False, interactive=False): source_dir = checkout_dir.joinpath("docs") - if release.lang != "en": + if release.lang != settings.DEFAULT_LANGUAGE_CODE: scm_url = release.scm_url.replace( "django.git", "django-docs-translations.git" ) diff --git a/docs/models.py b/docs/models.py index c3ca00ccba..d690c76bfc 100644 --- a/docs/models.py +++ b/docs/models.py @@ -47,9 +47,9 @@ def get_search_config(lang): class DocumentReleaseQuerySet(models.QuerySet): - def current(self, lang="en"): + def current(self, lang=settings.DEFAULT_LANGUAGE_CODE): current = self.get(is_default=True) - if lang != "en": + if lang != settings.DEFAULT_LANGUAGE_CODE: try: return self.get(lang=lang, release=current.release) except DocumentRelease.DoesNotExist: @@ -99,7 +99,9 @@ class DocumentRelease(models.Model): DEFAULT_CACHE_KEY = "%s_docs_version" % settings.CACHE_MIDDLEWARE_KEY_PREFIX - lang = models.CharField(max_length=7, choices=settings.LANGUAGES, default="en") + lang = models.CharField( + max_length=7, choices=settings.LANGUAGES, default=settings.DEFAULT_LANGUAGE_CODE + ) release = models.ForeignKey( Release, null=True, diff --git a/docs/templatetags/docs.py b/docs/templatetags/docs.py index 3410ec65cc..dc5c537774 100644 --- a/docs/templatetags/docs.py +++ b/docs/templatetags/docs.py @@ -2,6 +2,7 @@ from urllib.parse import quote from django import template +from django.conf import settings from django.template.defaultfilters import stringfilter from django.utils.safestring import mark_safe from django.utils.version import get_version_tuple @@ -38,7 +39,7 @@ def get_all_doc_versions(context, url=None): Usage: {% get_all_doc_versions as "varname" %} """ - lang = context.get("lang", "en") + lang = context.get("lang", settings.DEFAULT_LANGUAGE_CODE) versions = [] # Look for each version of the docs. diff --git a/docs/tests/test_models.py b/docs/tests/test_models.py index ad858419ff..4724cabeaa 100644 --- a/docs/tests/test_models.py +++ b/docs/tests/test_models.py @@ -122,9 +122,9 @@ def setUpTestData(cls): DocumentRelease.objects.bulk_create( DocumentRelease(lang=lang, release=release) for lang, release in [ - ("en", None), - ("en", r1), - ("en", r2), + (settings.DEFAULT_LANGUAGE_CODE, None), + (settings.DEFAULT_LANGUAGE_CODE, r1), + (settings.DEFAULT_LANGUAGE_CODE, r2), ("sv", r1), ("ar", r1), ] @@ -133,7 +133,7 @@ def setUpTestData(cls): def test_by_version(self): self.assertQuerySetEqual( DocumentRelease.objects.by_version("1.0"), - [("en", "1.0"), ("sv", "1.0"), ("ar", "1.0")], + [(settings.DEFAULT_LANGUAGE_CODE, "1.0"), ("sv", "1.0"), ("ar", "1.0")], transform=attrgetter("lang", "version"), ordered=False, ) @@ -141,7 +141,7 @@ def test_by_version(self): def test_by_version_dev(self): self.assertQuerySetEqual( DocumentRelease.objects.by_version("dev"), - [("en", "dev")], + [(settings.DEFAULT_LANGUAGE_CODE, "dev")], transform=attrgetter("lang", "version"), ordered=False, ) @@ -149,7 +149,12 @@ def test_by_version_dev(self): def test_by_versions(self): self.assertQuerySetEqual( DocumentRelease.objects.by_versions("1.0", "dev"), - [("en", "dev"), ("en", "1.0"), ("sv", "1.0"), ("ar", "1.0")], + [ + (settings.DEFAULT_LANGUAGE_CODE, "dev"), + (settings.DEFAULT_LANGUAGE_CODE, "1.0"), + ("sv", "1.0"), + ("ar", "1.0"), + ], transform=attrgetter("lang", "version"), ordered=False, ) @@ -159,9 +164,11 @@ def test_by_versions_empty(self): DocumentRelease.objects.by_versions() def test_get_by_version_and_lang_exists(self): - doc = DocumentRelease.objects.get_by_version_and_lang("1.0", "en") + doc = DocumentRelease.objects.get_by_version_and_lang( + "1.0", settings.DEFAULT_LANGUAGE_CODE + ) self.assertEqual(doc.release.version, "1.0") - self.assertEqual(doc.lang, "en") + self.assertEqual(doc.lang, settings.DEFAULT_LANGUAGE_CODE) def test_get_by_version_and_lang_missing(self): with self.assertRaises(DocumentRelease.DoesNotExist): @@ -169,8 +176,8 @@ def test_get_by_version_and_lang_missing(self): def test_get_available_languages_by_version(self): get = DocumentRelease.objects.get_available_languages_by_version - self.assertEqual(list(get("1.0")), ["ar", "en", "sv"]) - self.assertEqual(list(get("2.0")), ["en"]) + self.assertEqual(list(get("1.0")), ["ar", settings.DEFAULT_LANGUAGE_CODE, "sv"]) + self.assertEqual(list(get("2.0")), [settings.DEFAULT_LANGUAGE_CODE]) self.assertEqual(list(get("3.0")), []) @@ -444,7 +451,7 @@ def test_search_title(self): with self.assertNumQueries(1): self.assertQuerySetEqual( misspelled_query, - [("Generic views", "en", "1.2.3")], + [("Generic views", settings.DEFAULT_LANGUAGE_CODE, "1.2.3")], transform=attrgetter( "headline", "release.lang", "release.release.version" ), diff --git a/docs/tests/test_templates.py b/docs/tests/test_templates.py index 66f221eeff..6a370a847c 100644 --- a/docs/tests/test_templates.py +++ b/docs/tests/test_templates.py @@ -3,6 +3,7 @@ import tempfile from pathlib import Path +from django.conf import settings from django.template import Context, Template from django.template.loader import render_to_string from django.test import RequestFactory, TestCase @@ -27,8 +28,16 @@ def test_get_all_doc_versions_empty(self): def test_get_all_doc_versions(self): tmp_docs_build_root = Path(tempfile.mkdtemp()) self.addCleanup(shutil.rmtree, tmp_docs_build_root) - os.makedirs(tmp_docs_build_root.joinpath("en", "1.8", "_built", "json")) - os.makedirs(tmp_docs_build_root.joinpath("en", "1.11", "_built", "json")) + os.makedirs( + tmp_docs_build_root.joinpath( + settings.DEFAULT_LANGUAGE_CODE, "1.8", "_built", "json" + ) + ) + os.makedirs( + tmp_docs_build_root.joinpath( + settings.DEFAULT_LANGUAGE_CODE, "1.11", "_built", "json" + ) + ) with self.settings(DOCS_BUILD_ROOT=tmp_docs_build_root): self.assertEqual(get_all_doc_versions({}), ["1.8", "1.11", "dev"]) @@ -193,7 +202,7 @@ class TemplateTestCase(TestCase): def _assertOGTitleEqual(self, doc, expected): output = render_to_string( "docs/doc.html", - {"doc": doc, "lang": "en", "version": "5.0"}, + {"doc": doc, "lang": settings.DEFAULT_LANGUAGE_CODE, "version": "5.0"}, request=RequestFactory().get("/"), ) self.assertInHTML(f'', output) @@ -201,7 +210,7 @@ def _assertOGTitleEqual(self, doc, expected): def test_opengraph_title(self): doc = Document.objects.create( release=DocumentRelease.objects.create( - lang="en", + lang=settings.DEFAULT_LANGUAGE_CODE, release=Release.objects.create(version="5.0"), ), ) diff --git a/docs/tests/test_views.py b/docs/tests/test_views.py index 03129b6384..91681ebd1b 100644 --- a/docs/tests/test_views.py +++ b/docs/tests/test_views.py @@ -199,7 +199,11 @@ def test_code_links(self): base_url = reverse_with_host( "document-detail", host="docs", - kwargs={"lang": "en", "version": "5.1", "url": "refs/query"}, + kwargs={ + "lang": settings.DEFAULT_LANGUAGE_CODE, + "version": "5.1", + "url": "refs/query", + }, ) for query, expected_code_links in [ ( @@ -247,7 +251,9 @@ def test_sitemap_index(self): ) self.assertContains(response, "", count=2) en_sitemap_url = reverse_with_host( - "document-sitemap", host="docs", kwargs={"section": "en"} + "document-sitemap", + host="docs", + kwargs={"section": settings.DEFAULT_LANGUAGE_CODE}, ) self.assertContains(response, f"{en_sitemap_url}") diff --git a/docs/views_debug.py b/docs/views_debug.py index f2813211c8..0bd405e9cc 100644 --- a/docs/views_debug.py +++ b/docs/views_debug.py @@ -1,3 +1,4 @@ +from django.conf import settings from django.views import static from .models import DocumentRelease @@ -24,5 +25,7 @@ def objects_inventory(request, lang, version): def pot_file(request, pot_name): version = DocumentRelease.objects.current().version - doc_root = get_doc_root_or_404("en", version, builder="gettext") + doc_root = get_doc_root_or_404( + settings.DEFAULT_LANGUAGE_CODE, version, builder="gettext" + ) return static.serve(request, document_root=doc_root, path=pot_name) diff --git a/releases/templatetags/release_notes.py b/releases/templatetags/release_notes.py index 4d2fd45bc5..4e9d6cced0 100644 --- a/releases/templatetags/release_notes.py +++ b/releases/templatetags/release_notes.py @@ -1,4 +1,5 @@ from django import template +from django.conf import settings from django.utils.html import format_html from django.utils.translation import gettext as _ from django_hosts.resolvers import reverse @@ -26,7 +27,7 @@ def release_notes(version, show_version=False): "document-detail", host="docs", kwargs={ - "lang": "en", + "lang": settings.DEFAULT_LANGUAGE_CODE, "version": version_x_dot_y, "url": release_notes_path, }, From 7662ced3972099631e2fbf25b6dfaf75cd2011ea Mon Sep 17 00:00:00 2001 From: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> Date: Fri, 17 Oct 2025 18:54:18 +0200 Subject: [PATCH 2/3] Moved docs search bar to top navigation in prep for global search. --- accounts/tests.py | 8 +- aggregator/tests.py | 4 +- blog/tests.py | 6 +- contact/tests.py | 4 +- dashboard/tests.py | 3 +- djangoproject/scss/_dark-mode.scss | 22 +++-- djangoproject/scss/_style.scss | 86 +++++++++---------- djangoproject/static/img/logo-dj.svg | 10 +++ djangoproject/templates/includes/header.html | 11 ++- .../templates}/search_form.html | 0 djangoproject/tests.py | 23 ++--- djangoproject/utils.py | 36 ++++++++ docs/forms.py | 8 +- docs/templates/base_docs.html | 3 +- docs/templatetags/docs.py | 33 +++++-- docs/tests/test_templates.py | 38 ++++++++ foundation/tests.py | 5 +- fundraising/tests/test_views.py | 12 +-- legacy/tests.py | 4 +- members/test_views.py | 16 ++-- releases/tests.py | 7 +- svntogit/tests.py | 4 +- tracdb/tests.py | 4 +- 23 files changed, 244 insertions(+), 103 deletions(-) create mode 100644 djangoproject/static/img/logo-dj.svg rename {docs/templates/docs => djangoproject/templates}/search_form.html (100%) create mode 100644 djangoproject/utils.py diff --git a/accounts/tests.py b/accounts/tests.py index c41d893b1a..c90377e919 100644 --- a/accounts/tests.py +++ b/accounts/tests.py @@ -6,17 +6,19 @@ from django_hosts.resolvers import reverse from accounts.forms import DeleteProfileForm +from djangoproject.tests import ReleaseMixin from foundation import models as foundationmodels from tracdb.models import Revision, Ticket, TicketChange from tracdb.testutils import TracDBCreateDatabaseMixin @override_settings(TRAC_URL="https://code.djangoproject.com/") -class UserProfileTests(TracDBCreateDatabaseMixin, TestCase): +class UserProfileTests(TracDBCreateDatabaseMixin, ReleaseMixin, TestCase): databases = {"default", "trac"} @classmethod def setUpTestData(cls): + super().setUpTestData() User.objects.create_user(username="user1", password="password") User.objects.create_user(username="user2", password="password") cls.user1_url = reverse("user_profile", args=["user1"]) @@ -175,7 +177,7 @@ def test_caches_trac_stats(self): self.assertIsNotNone(cache.get(key)) -class ViewsTests(TestCase): +class ViewsTests(ReleaseMixin, TestCase): def test_login_redirect(self): credentials = {"username": "a-user", "password": "password"} @@ -193,7 +195,7 @@ def test_profile_view_reversal(self): reverse("user_profile", host="www", args=[username]) -class UserDeletionTests(TestCase): +class UserDeletionTests(ReleaseMixin, TestCase): def create_user_and_form(self, bound=True, **userkwargs): userkwargs.setdefault("username", "test") userkwargs.setdefault("email", "test@example.com") diff --git a/aggregator/tests.py b/aggregator/tests.py index 2c28d57812..a8e583decf 100644 --- a/aggregator/tests.py +++ b/aggregator/tests.py @@ -92,7 +92,7 @@ def setUp(self, mocker): def test_community_index_number_of_queries(self): """Intended to prevent an n+1 issue on the community index view""" url = reverse("community-index") - with self.assertNumQueries(6): + with self.assertNumQueries(7): self.client.get(url) def test_empty_feed_type_not_rendered(self): @@ -119,7 +119,7 @@ def test_feed_list_number_of_queries(self): url = reverse( "community-feed-list", kwargs={"feed_type_slug": self.feed_type.slug} ) - with self.assertNumQueries(7): + with self.assertNumQueries(8): self.client.get(url) def test_management_command_sends_no_email_with_no_pending_feeds(self): diff --git a/blog/tests.py b/blog/tests.py index 39cf4824c6..f67bc7ea16 100644 --- a/blog/tests.py +++ b/blog/tests.py @@ -13,6 +13,8 @@ from django.urls import reverse from django.utils import timezone, translation +from djangoproject.tests import ReleaseMixin + from .models import ContentFormat, Entry, Event, ImageUpload from .sitemaps import WeblogSitemap @@ -210,7 +212,7 @@ def test_past_future_ordering(self): ) -class ViewsTestCase(DateTimeMixin, TestCase): +class ViewsTestCase(ReleaseMixin, DateTimeMixin, TestCase): def test_detail_view_html_meta(self): headline = "Pride and Prejudice - Review" author = "Jane Austen" @@ -474,7 +476,7 @@ def test_user_cannot_see_unpublished_entries(self): + ["django.middleware.cache.FetchFromCacheMiddleware"] ), ) -class ViewsCachingTestCase(DateTimeMixin, TestCase): +class ViewsCachingTestCase(ReleaseMixin, DateTimeMixin, TestCase): def test_drafts_have_no_cache_headers(self): """ Draft (unpublished) entries have no-cache headers. diff --git a/contact/tests.py b/contact/tests.py index a11ea52241..cf5f0b5028 100644 --- a/contact/tests.py +++ b/contact/tests.py @@ -6,6 +6,8 @@ from django.test import TestCase from django.test.utils import override_settings +from djangoproject.tests import ReleaseMixin + from .views import FoundationContactForm @@ -21,7 +23,7 @@ def check_network_connection(): @override_settings(AKISMET_TESTING=True) -class ContactFormTests(TestCase): +class ContactFormTests(ReleaseMixin, TestCase): def setUp(self): self.url = "/contact/foundation/" diff --git a/dashboard/tests.py b/dashboard/tests.py index 577158959e..5049825067 100644 --- a/dashboard/tests.py +++ b/dashboard/tests.py @@ -9,6 +9,7 @@ from django.test import RequestFactory, TestCase from django_hosts.resolvers import reverse +from djangoproject.tests import ReleaseMixin from tracdb.models import Ticket from tracdb.testutils import TracDBCreateDatabaseMixin from tracdb.tractime import datetime_to_timestamp @@ -24,7 +25,7 @@ from .views import index, metric_detail, metric_json -class ViewTests(TestCase): +class ViewTests(ReleaseMixin, TestCase): fixtures = ["dashboard_test_data"] def setUp(self): diff --git a/djangoproject/scss/_dark-mode.scss b/djangoproject/scss/_dark-mode.scss index 53c981ec1f..1544aa6872 100644 --- a/djangoproject/scss/_dark-mode.scss +++ b/djangoproject/scss/_dark-mode.scss @@ -347,20 +347,28 @@ html[data-theme="light"] .theme-toggle .theme-label-when-light { background-color: var(--body-bg); } -.mobile-toggle { - width: 45px; - height: 45px; +// Section of the header that is only visible on mobile. +.header-mobile-only { line-height: 45px; text-align: center; - margin: 4px 10px; + display: flex; + align-items: center; - @include respond-min(768px) { + @include respond-min(1080px) { display: none; } + + .light-dark-mode-toggle { + height: 45px; + width: 45px; + margin: 2px; + } } -header nav li:last-child { - @include respond-max(768px) { +// The last 2 items of the nav list are the searchbar and the light/dark mode toggle. +// These are not visible on mobile as they are within the .header-mobile-only section. +header nav li:nth-last-child(-n+2) { + @include respond-max(1080px) { display: none; } } diff --git a/djangoproject/scss/_style.scss b/djangoproject/scss/_style.scss index 125a6304e0..08a9a834fd 100644 --- a/djangoproject/scss/_style.scss +++ b/djangoproject/scss/_style.scss @@ -425,7 +425,6 @@ main { .container { @include respond-min(768px) { margin: 0 auto; - max-width: 1400px; padding: 0 (32/768) * 100%; } @@ -463,13 +462,10 @@ header { .container { display: flex; - flex-direction: row; - @include respond-min(768px) { - position: relative; - } + align-items: center; } - .mobile-toggle {margin-left: auto} + .header-mobile-only {margin-left: auto} .meta { @include font-size(13); @@ -479,7 +475,7 @@ header { margin: 8px 0 0 10px; display: none; - @include respond-min(1150px) { + @include respond-min(1080px) { width: 200px; display: block; } @@ -490,19 +486,26 @@ header { .logo { @include font-size(40); @include sans-serif; - background: url(../img/logo-django.svg) center center no-repeat; + // Small screens less than 500px use the dj logo. This gives more + // horizontal space for a searchbar in the header. + background: url(../img/logo-dj.svg) center center no-repeat; color: var(--white-color); display: block; font-weight: 700; - margin: 10px; + margin: 10px 4px; overflow: hidden; text-decoration: none; text-indent: 100%; - width: 104px; + width: 45px; height: 36px; - @include respond-min(768px) { - margin-left: 0; + @include respond-min(500px) { + background: url(../img/logo-django.svg) center center no-repeat; + width: 104px; + } + + @include respond-min(1080px) { + margin-left: 10px; } } @@ -514,13 +517,12 @@ header { cursor: pointer; display: block; height: 45px; - line-height: 48px; - margin: 4px 10px; + margin: 2px; text-align: center; text-decoration: none; width: 45px; - @include respond-min(768px) { + @include respond-min(1080px) { display: none; } @@ -544,7 +546,7 @@ header { max-height: 580px; } - @include respond-min(768px) { + @include respond-min(1080px) { width: auto; max-height: none; // always show menu on a desktop width } @@ -553,7 +555,9 @@ header { margin: 10px 0 0; padding: 0; - @include respond-min(768px) { + @include respond-min(1080px) { + display: flex; + align-items: center; margin: 0; } } @@ -568,14 +572,18 @@ header { text-transform: uppercase; margin: 0 10px; border-top: 1px solid lighten($green-dark, 5%); - padding: 20px 0px; + > :not(.search){ + padding: 20px 0px; + } - @include respond-min(768px) { + @include respond-min(1080px) { margin: 0; border: 0; float: left; text-align: left; - padding: 20px 10px; + > :not(.search){ + padding: 10px; + } } &.active a { @@ -608,18 +616,11 @@ header { color: var(--secondary-accent); } - @include respond-min(768px) { + @include respond-min(1080px) { padding: 20px 10px; } } - .nav-primary { - @include respond-min(768px) { - position: absolute; - right: 0; - top: 45px; - } - } } } @@ -645,7 +646,7 @@ header { top: 0; max-width: 660px; - @include respond-min(768px) { + @include respond-min(1080px) { position: static; } } @@ -3008,14 +3009,10 @@ form { height: 40px; padding: 0; position: absolute; - right: 2%; + right: 0; top: 6%; width: 40px; - @include respond-min(768px) { - right: 1%; - } - i { @include font-size(20); line-height: 1; @@ -3057,16 +3054,15 @@ form { } &.search { - @include respond-min(768px) { - flex: 0 0 40%; - margin: 10px 0; - } - - flex: 0 0 100%; - margin: 0 0 10px 0; - - button { - top: 19%; + width: 20%; + min-width: 200px; + margin: 10px; + margin-left: 0; + input { + margin: 0; + @include respond-min(1080px) { + margin: 0 10px; + } } } } @@ -3605,7 +3601,7 @@ ul.corporate-members li { justify-content: space-between; } - @include respond-max(1200px) { + @include respond-max(1080px) { .community-title { text-align: center; } diff --git a/djangoproject/static/img/logo-dj.svg b/djangoproject/static/img/logo-dj.svg new file mode 100644 index 0000000000..5ecd24d91d --- /dev/null +++ b/djangoproject/static/img/logo-dj.svg @@ -0,0 +1,10 @@ + + + django-dj-centered + + + + + + + diff --git a/djangoproject/templates/includes/header.html b/djangoproject/templates/includes/header.html index 8c9da6cd65..29ae32900f 100644 --- a/djangoproject/templates/includes/header.html +++ b/djangoproject/templates/includes/header.html @@ -1,3 +1,4 @@ +{% load docs %} {% if 'preview.djangoproject.com' in request.get_host %}
{% endif %} @@ -5,8 +6,11 @@

The web framework for perfectionists with deadlines.

-
- {% include "includes/toggle_theme.html" %} +
+ {% search_form %} +
+ {% include "includes/toggle_theme.html" %} +