From f8d5cc5ba57bac922cc7532f072f5dbc965bf48e Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Mon, 25 Jul 2022 21:58:06 +0100 Subject: [PATCH] Add feeds to blog list pages --- website/blog/models.py | 22 ++++++++++++++++++++-- website/blog/views.py | 40 ++++++++++++++++++++++++++++++++++++++++ website/settings.py | 1 + 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 website/blog/views.py diff --git a/website/blog/models.py b/website/blog/models.py index 9c518d5..f45d994 100644 --- a/website/blog/models.py +++ b/website/blog/models.py @@ -3,17 +3,19 @@ from typing import Any from django.db import models from django.db.models.functions import TruncMonth from django.http.request import HttpRequest +from django.http.response import HttpResponse from django.utils import timezone from django.utils.functional import cached_property from modelcluster.fields import ParentalManyToManyField from wagtail.admin.panels import FieldPanel +from wagtail.contrib.routable_page.models import RoutablePageMixin, route from wagtail.query import PageQuerySet from website.common.models import BaseContentMixin, BasePage from website.common.utils import TocEntry -class BlogListPage(BaseContentMixin, BasePage): # type: ignore[misc] +class BlogListPage(BaseContentMixin, RoutablePageMixin, BasePage): # type: ignore[misc] max_count = 1 subpage_types = [ "blog.BlogPostPage", @@ -59,6 +61,14 @@ class BlogListPage(BaseContentMixin, BasePage): # type: ignore[misc] ) return context + @route(r"^feed/$") + def feed(self, request: HttpRequest) -> HttpResponse: + from .views import BlogPostPageFeed + + return BlogPostPageFeed( + self.get_blog_posts().order_by("-date"), self.get_url(), self.title + )(request) + class BlogPostPage(BaseContentMixin, BasePage): # type: ignore[misc] subpage_types: list[Any] = [] @@ -94,7 +104,7 @@ class BlogPostTagListPage(BaseContentMixin, BasePage): # type: ignore[misc] return context -class BlogPostTagPage(BaseContentMixin, BasePage): # type: ignore[misc] +class BlogPostTagPage(BaseContentMixin, RoutablePageMixin, BasePage): # type: ignore[misc] subpage_types: list[Any] = [] parent_page_types = [BlogPostTagListPage] @@ -117,6 +127,14 @@ class BlogPostTagPage(BaseContentMixin, BasePage): # type: ignore[misc] context["pages"] = self.get_blog_posts() return context + @route(r"^feed/$") + def feed(self, request: HttpRequest) -> HttpResponse: + from .views import BlogPostPageFeed + + return BlogPostPageFeed( + self.get_blog_posts().order_by("-date"), self.get_url(), self.title + )(request) + class BlogCollectionListPage(BaseContentMixin, BasePage): # type: ignore[misc] subpage_types: list[Any] = [] diff --git a/website/blog/views.py b/website/blog/views.py new file mode 100644 index 0000000..b99a3f6 --- /dev/null +++ b/website/blog/views.py @@ -0,0 +1,40 @@ +from datetime import datetime, time + +from django.contrib.syndication.views import Feed +from django.http.request import HttpRequest +from django.http.response import HttpResponse +from wagtail.query import PageQuerySet + +from .models import BlogPostPage + + +class BlogPostPageFeed(Feed): + def __init__(self, posts: PageQuerySet, link: str, title: str): + self.posts = posts + self.link = link + self.title = title + super().__init__() + + def __call__( + self, request: HttpRequest, *args: list, **kwargs: dict + ) -> HttpResponse: + self.request = request + return super().__call__(request, *args, **kwargs) + + def items(self) -> PageQuerySet: + return self.posts + + def item_title(self, item: BlogPostPage) -> str: + return item.title + + def item_link(self, item: BlogPostPage) -> str: + return item.get_full_url(request=self.request) + + def item_description(self, item: BlogPostPage) -> str: + return item.summary + + def item_pubdate(self, item: BlogPostPage) -> datetime: + return datetime.combine(item.date, time()) + + def item_updateddate(self, item: BlogPostPage) -> datetime: + return item.last_published_at diff --git a/website/settings.py b/website/settings.py index 10ba888..fa3453c 100644 --- a/website/settings.py +++ b/website/settings.py @@ -35,6 +35,7 @@ INSTALLED_APPS = [ "wagtail.contrib.forms", "wagtail.contrib.redirects", "wagtail.contrib.modeladmin", + "wagtail.contrib.routable_page", "wagtail.embeds", "wagtail.sites", "wagtail.users",