Skip to content

Commit 6d7606a

Browse files
committed
Added static views to sitemap.
1 parent bd21967 commit 6d7606a

File tree

5 files changed

+112
-28
lines changed

5 files changed

+112
-28
lines changed

djangoproject/sitemaps.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
from dataclasses import dataclass
2+
3+
from django.contrib import sitemaps
4+
from django_hosts.resolvers import reverse
5+
6+
7+
@dataclass
8+
class URLObject:
9+
name: str
10+
host: str = "www"
11+
12+
13+
class LocationAbsoluteUrlMixin:
14+
def get_urls(self, site=None, **kwargs):
15+
"""
16+
Prevent the Django sitemap framework from prefixing the domain.
17+
Use the absolute URL returned by location().
18+
"""
19+
urls = []
20+
for item in self.items():
21+
loc = self.location(item)
22+
urls.append(
23+
{
24+
"location": loc,
25+
"lastmod": None,
26+
"changefreq": self.changefreq,
27+
"priority": self.priority,
28+
}
29+
)
30+
return urls
31+
32+
33+
class StaticViewSitemap(LocationAbsoluteUrlMixin, sitemaps.Sitemap):
34+
priority = 0.5
35+
changefreq = "monthly"
36+
37+
def items(self):
38+
return [
39+
# accounts
40+
URLObject("registration_register"),
41+
# aggregator
42+
URLObject("community-index"),
43+
URLObject("community-ecosystem"),
44+
URLObject("local-django-communities"),
45+
# contact
46+
URLObject("contact_foundation"),
47+
# dashboard
48+
URLObject("dashboard-index", host="dashboard"),
49+
URLObject("metric-list", host="dashboard"),
50+
# djangoproject
51+
URLObject("homepage"),
52+
URLObject("overview"),
53+
URLObject("start"),
54+
URLObject("code_of_conduct"),
55+
URLObject("conduct_faq"),
56+
URLObject("conduct_reporting"),
57+
URLObject("conduct_enforcement"),
58+
URLObject("conduct_changes"),
59+
URLObject("diversity"),
60+
URLObject("diversity_changes"),
61+
# foundation
62+
URLObject("foundation_meeting_archive_index"),
63+
# fundraising
64+
URLObject("fundraising:index"),
65+
# members
66+
URLObject("members:individual-members"),
67+
URLObject("members:corporate-members"),
68+
URLObject("members:corporate-members-join"),
69+
URLObject("members:corporate-members-badges"),
70+
URLObject("members:teams"),
71+
# releases
72+
URLObject("download"),
73+
]
74+
75+
def location(self, item):
76+
return reverse(item.name, host=item.host)

djangoproject/tests.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ def test_single_h1_per_page(self):
202202
"styleguide/", # Has multiple <h1> examples.
203203
"admin/", # Admin templates are out of our control.
204204
"reset/done/", # Uses an admin template.
205+
"sitemap.xml",
205206
]
206207
resolver = get_resolver()
207208
urls = self.extract_patterns(resolver.url_patterns)
@@ -211,3 +212,9 @@ def test_single_h1_per_page(self):
211212
response = self.client.get(url)
212213
self.assertEqual(response.status_code, 200)
213214
self.assertContains(response, "<h1", count=1)
215+
216+
217+
class SiteMapTests(TestCase):
218+
def test_sitemap_renders(self):
219+
response = self.client.get(reverse("sitemap"))
220+
self.assertEqual(response.status_code, 200)

djangoproject/urls/www.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from aggregator.feeds import CommunityAggregatorFeed, CommunityAggregatorFirehoseFeed
1414
from blog.feeds import WeblogEntryFeed
1515
from blog.sitemaps import WeblogSitemap
16+
from djangoproject.sitemaps import StaticViewSitemap
1617
from foundation.feeds import FoundationMinutesFeed
1718
from foundation.views import CoreDevelopers
1819

@@ -21,6 +22,7 @@
2122
sitemaps = {
2223
"weblog": WeblogSitemap,
2324
"flatpages": FlatPageSitemap,
25+
"static": StaticViewSitemap,
2426
}
2527

2628

@@ -135,6 +137,7 @@
135137
"sitemap.xml",
136138
cache_page(60 * 60 * 6)(sitemap_views.sitemap),
137139
{"sitemaps": sitemaps},
140+
name="sitemap",
138141
),
139142
path("weblog/", include("blog.urls")),
140143
path("download/", include("releases.urls")),

docs/sitemaps.py

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
from django.contrib.sitemaps import Sitemap
22

3+
from djangoproject.sitemaps import LocationAbsoluteUrlMixin
4+
35
from .models import Document
46
from .search import DocumentationCategory
57

68

7-
class DocsSitemap(Sitemap):
9+
class DocsSitemap(LocationAbsoluteUrlMixin, Sitemap):
810
def __init__(self, lang):
911
self.lang = lang
1012

@@ -16,6 +18,9 @@ def items(self):
1618
.select_related("release__release")
1719
)
1820

21+
def location(self, item):
22+
return item.get_absolute_url()
23+
1924
def changefreq(self, obj):
2025
return "daily"
2126

@@ -33,19 +38,3 @@ def priority(self, obj):
3338
return 1
3439
else:
3540
return 0.1
36-
37-
def _urls(self, page, site, protocol):
38-
# XXX: To workaround bad interaction between contrib.sitemaps and
39-
# django-hosts (scheme/domain would be repeated twice in URLs)
40-
urls = []
41-
for item in self.paginator.page(page).object_list:
42-
loc = item.get_absolute_url()
43-
priority = self.priority(item)
44-
url_info = {
45-
"item": item,
46-
"location": loc,
47-
"changefreq": self.changefreq(item),
48-
"priority": str(priority if priority is not None else ""),
49-
}
50-
urls.append(url_info)
51-
return urls

docs/tests/test_models.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
from django.db import connection
88
from django.test import TestCase
99
from django.utils import timezone
10+
from django_hosts import reverse
1011

1112
from blog.models import ContentFormat, Entry
13+
from djangoproject.sitemaps import StaticViewSitemap
1214
from releases.models import Release
1315

1416
from ..models import Document, DocumentRelease
@@ -607,7 +609,7 @@ def test_sync_to_db_not_delete_website_docs(self):
607609

608610
def test_sync_from_sitemap_skip_non_en_dev_release(self):
609611
release = Release.objects.create(version="5.2")
610-
Entry.objects.create(
612+
blog_entry = Entry.objects.create(
611613
pub_date=timezone.now() - datetime.timedelta(days=2),
612614
slug="a",
613615
body="<strong>test</strong>",
@@ -625,7 +627,16 @@ def test_sync_from_sitemap_skip_non_en_dev_release(self):
625627
)
626628
with self.subTest(lang=lang, release=release_obj):
627629
doc_release.sync_from_sitemap()
628-
self.assertFalse(Document.objects.exists())
630+
self.assertFalse(
631+
Document.objects.filter(path=blog_entry.get_absolute_url()).exists()
632+
)
633+
634+
@staticmethod
635+
def _mock_static_sitemap_urls(mocker):
636+
sitemap = StaticViewSitemap()
637+
for item in sitemap.items():
638+
url = reverse(item.name, host=item.host)
639+
mocker.get(url, text="", headers={"Content-Type": "text/html"})
629640

630641
@requests_mock.mock()
631642
def test_sync_from_sitemap(self, mocker):
@@ -636,17 +647,16 @@ def test_sync_from_sitemap(self, mocker):
636647
content_format=ContentFormat.HTML,
637648
is_active=True,
638649
)
650+
self._mock_static_sitemap_urls(mocker)
639651
mocker.get(
640652
blog_entry.get_absolute_url(),
641653
text="<html><main>Main 1</main><h1>Title 1</h1></html>",
642654
headers={"Content-Type": "text/html"},
643655
)
644656
self.release.sync_from_sitemap()
645657

646-
document = Document.objects.get(release=self.release)
647-
self.assertEqual(
648-
document.path,
649-
blog_entry.get_absolute_url(),
658+
document = Document.objects.get(
659+
release=self.release, path=blog_entry.get_absolute_url()
650660
)
651661
self.assertEqual(
652662
document.title,
@@ -683,12 +693,10 @@ def test_sync_from_sitemap_only_requests_non_existing(self, mock_fetch_html):
683693

684694
mock_fetch_html.assert_not_called()
685695

686-
document = Document.objects.get(release=self.release)
687-
# Confirm Document has not been updated.
688-
self.assertEqual(
689-
document.path,
690-
blog_entry.get_absolute_url(),
696+
document = Document.objects.get(
697+
release=self.release, path=blog_entry.get_absolute_url()
691698
)
699+
# Confirm Document has not been updated.
692700
self.assertEqual(
693701
document.metadata,
694702
{"parents": DocumentationCategory.WEBSITE},
@@ -714,6 +722,7 @@ def test_sync_from_sitemap_force(self, mocker):
714722
metadata={"parents": DocumentationCategory.WEBSITE},
715723
path=blog_url,
716724
)
725+
self._mock_static_sitemap_urls(mocker)
717726
mocker.get(
718727
blog_url,
719728
text="<html><main>Main 1</main><h1>Title 1</h1></html>",

0 commit comments

Comments
 (0)