From 5bb0801f159ae7809f3b0ba15f6e20590c8437ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Hells=C3=A9n?= Date: Fri, 23 Feb 2024 14:43:32 +0100 Subject: [PATCH] Add sitemaps --- feeds/models.py | 14 +++++++++++--- feeds/sitemaps.py | 18 ++++++++++++++++++ feeds/urls.py | 17 +++++++++++++++++ feedvault/settings.py | 1 + 4 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 feeds/sitemaps.py diff --git a/feeds/models.py b/feeds/models.py index 65e324d..47014df 100644 --- a/feeds/models.py +++ b/feeds/models.py @@ -25,7 +25,7 @@ class Domain(models.Model): class Meta: """Meta information for the domain model.""" - ordering: typing.ClassVar[list[str]] = ["name"] # Example: Orders by name alphabetically + ordering: typing.ClassVar[list[str]] = ["name"] verbose_name: str = "Domain" verbose_name_plural: str = "Domains" @@ -34,6 +34,10 @@ class Domain(models.Model): if_hidden: Literal[" (hidden)", ""] = " (hidden)" if self.hidden else "" return self.name + if_hidden + def get_absolute_url(self) -> str: + """Return the absolute URL of the domain.""" + return f"/domain/{self.pk}/" + class Author(models.Model): """An author of an entry.""" @@ -48,7 +52,7 @@ class Author(models.Model): """Meta information for the author model.""" unique_together: typing.ClassVar[list[str]] = ["name", "email", "href"] - ordering: typing.ClassVar[list[str]] = ["name"] # Example: Orders by name alphabetically + ordering: typing.ClassVar[list[str]] = ["name"] verbose_name: str = "Author" verbose_name_plural: str = "Authors" @@ -70,7 +74,7 @@ class Generator(models.Model): """Meta information for the generator model.""" unique_together: typing.ClassVar[list[str]] = ["name", "version", "href"] - ordering: typing.ClassVar[list[str]] = ["name"] # Example: Orders by name alphabetically + ordering: typing.ClassVar[list[str]] = ["name"] verbose_name: str = "Feed generator" verbose_name_plural: str = "Feed generators" @@ -216,6 +220,10 @@ class Feed(models.Model): """Return string representation of the feed.""" return f"{self.domain} - {self.title}" + def get_absolute_url(self) -> str: + """Return the absolute URL of the feed.""" + return f"/feed/{self.pk}/" + class Entry(models.Model): """Each feed has multiple entries.""" diff --git a/feeds/sitemaps.py b/feeds/sitemaps.py new file mode 100644 index 0000000..f8c7d4d --- /dev/null +++ b/feeds/sitemaps.py @@ -0,0 +1,18 @@ +from __future__ import annotations + +from django.contrib.sitemaps import Sitemap +from django.urls import reverse + + +class StaticViewSitemap(Sitemap): + """Sitemap for static views.""" + + changefreq: str = "daily" + priority: float = 0.5 + + def items(self: StaticViewSitemap) -> list[str]: + """Return all the items in the sitemap.""" + return ["feeds:index", "feeds:feeds", "feeds:domains"] + + def location(self, item) -> str: + return reverse(item) diff --git a/feeds/urls.py b/feeds/urls.py index 21cb99d..7f21844 100644 --- a/feeds/urls.py +++ b/feeds/urls.py @@ -1,14 +1,25 @@ from __future__ import annotations +from django.contrib.sitemaps import GenericSitemap +from django.contrib.sitemaps.views import sitemap from django.urls import URLPattern, path from django.views.decorators.cache import cache_page from feeds import views +from feeds.models import Domain, Feed +from feeds.sitemaps import StaticViewSitemap from .views import APIView, CustomLoginView, CustomLogoutView, ProfileView, RegisterView app_name: str = "feeds" +sitemaps = { + "static": StaticViewSitemap, + "feeds": GenericSitemap({"queryset": Feed.objects.all(), "date_field": "created_at"}), + "domains": GenericSitemap({"queryset": Domain.objects.all(), "date_field": "created_at"}), +} + + # Normal pages urlpatterns: list[URLPattern] = [ path(route="", view=views.IndexView.as_view(), name="index"), @@ -17,6 +28,12 @@ urlpatterns: list[URLPattern] = [ path(route="add", view=views.AddView.as_view(), name="add"), path(route="upload", view=views.UploadView.as_view(), name="upload"), path(route="robots.txt", view=cache_page(timeout=60 * 60 * 365)(views.RobotsView.as_view()), name="robots"), + path( + "sitemap.xml", + sitemap, + {"sitemaps": sitemaps}, + name="django.contrib.sitemaps.views.sitemap", + ), path(route="domains/", view=views.DomainsView.as_view(), name="domains"), path(route="domain//", view=views.DomainView.as_view(), name="domain"), ] diff --git a/feedvault/settings.py b/feedvault/settings.py index d20d0f5..7df5d46 100644 --- a/feedvault/settings.py +++ b/feedvault/settings.py @@ -25,6 +25,7 @@ INSTALLED_APPS: list[str] = [ "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", + "django.contrib.sitemaps", ] MIDDLEWARE: list[str] = [