Unify RSS feeds

One per section is a little much. Just use a single feed and be done with. Might help discoverability a little.
This commit is contained in:
Jake Howard 2023-12-22 17:35:18 +00:00
parent aa5107c89e
commit e5ae66567a
Signed by: jake
GPG key ID: 57AFB45680EDD477
8 changed files with 27 additions and 83 deletions

View file

@ -1,4 +1,5 @@
from django.test import TestCase
from django.urls import reverse
from website.home.models import HomePage
@ -73,17 +74,13 @@ class BlogPostListPageTestCase(TestCase):
response = self.client.get(self.page.url)
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.context["listing_pages"]), 2)
self.assertContains(response, self.page.reverse_subpage("feed"))
def test_queries(self) -> None:
with self.assertNumQueries(44):
self.client.get(self.page.url)
def test_feed_accessible(self) -> None:
with self.assertNumQueries(14):
response = self.client.get(
self.page.url + self.page.reverse_subpage("feed")
response = self.client.get(self.page.url + self.page.reverse_subpage("feed"))
self.assertRedirects(
response, reverse("feed"), status_code=301, fetch_redirect_response=True
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response["Content-Type"], "application/xml")
self.assertContains(response, "xml-stylesheet")

View file

@ -1,19 +1,17 @@
from datetime import timedelta
from typing import Any, Optional, Type
from typing import Any, Optional
from urllib.parse import urlencode
from django.contrib.humanize.templatetags.humanize import NaturalTimeFormatter
from django.contrib.syndication.views import Feed
from django.core.paginator import EmptyPage, Paginator
from django.core.paginator import Page as PaginatorPage
from django.db import models
from django.http.request import HttpRequest
from django.http.response import Http404, HttpResponse, HttpResponseBadRequest
from django.shortcuts import redirect
from django.utils import timezone
from django.utils.decorators import method_decorator
from django.utils.functional import cached_property, classproperty
from django.utils.text import slugify
from django.views.decorators.cache import cache_page
from wagtail.admin.panels import FieldPanel, MultiFieldPanel
from wagtail.contrib.routable_page.models import RoutablePageMixin, route
from wagtail.contrib.settings.models import BaseGenericSetting, register_setting
@ -257,12 +255,6 @@ class BaseListingPage(RoutablePageMixin, BaseContentPage):
def show_reading_time(self) -> bool:
return False
@property
def feed_class(self) -> Type[Feed]:
from .views import ContentPageFeed
return ContentPageFeed
@route(r"^$")
def index_route(self, request: HttpRequest) -> HttpResponse:
self.serializer = PaginationSerializer(data=request.GET)
@ -283,13 +275,8 @@ class BaseListingPage(RoutablePageMixin, BaseContentPage):
return url + "?" + urlencode(query_data)
@route(r"^feed/$")
@method_decorator(cache_page(60 * 30))
def feed(self, request: HttpRequest) -> HttpResponse:
return self.feed_class(
self.get_listing_pages(),
self.get_full_url(request),
self.html_title_tag,
)(request)
return redirect("feed", permanent=True)
class ListingPage(BaseListingPage):

View file

@ -1,15 +1,8 @@
{% extends "common/content_page.html" %}
{% load wagtailroutablepage_tags wagtailadmin_tags %}
{% block extra_head %}
{{ block.super }}
<link rel="alternate" type="application/rss+xml" href="{% routablepageurl page 'feed' %}" />
{% endblock %}
{% load wagtailadmin_tags %}
{% block hero_buttons %}
<a class="button is-radiusless" href="{% routablepageurl page 'feed' %}" title="View feed"><i class="fas fa-rss" aria-hidden="true"></i></a>
{% if listing_pages.has_previous %}
<a class="button is-radiusless" href="{% querystring page=listing_pages.previous_page_number %}" title="Previous page"><i class="fas fa-arrow-left" aria-hidden="true"></i></a>
{% endif %}

View file

@ -1,5 +1,6 @@
from django.template.loader import get_template
from django.test import SimpleTestCase, TestCase
from django.urls import reverse
from website.common.factories import ContentPageFactory, ListingPageFactory
from website.common.models import BaseListingPage, BasePage
@ -58,14 +59,11 @@ class ListingPageTestCase(TestCase):
self.assertEqual(len(response.context["listing_pages"]), 2)
self.assertContains(response, self.page.reverse_subpage("feed"))
def test_feed_accessible(self) -> None:
with self.assertNumQueries(13):
response = self.client.get(
self.page.url + self.page.reverse_subpage("feed")
def test_feed_redirects(self) -> None:
response = self.client.get(self.page.url + self.page.reverse_subpage("feed"))
self.assertRedirects(
response, reverse("feed"), status_code=301, fetch_redirect_response=True
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response["Content-Type"], "application/xml")
self.assertContains(response, "xml-stylesheet")
def test_meta_url(self) -> None:
response = self.client.get(self.page.url)

View file

@ -93,7 +93,7 @@ class AllPagesFeed(Feed):
return {**super().feed_extra_kwargs(obj), "request": self.request}
def title(self) -> str:
return f"All Pages Feed :: {get_site_title()}"
return f"Feed :: {get_site_title()}"
def items(self) -> PageQuerySet:
return (
@ -149,20 +149,6 @@ class AllPagesFeed(Feed):
item_enclosure_length = 0
class ContentPageFeed(AllPagesFeed):
def __init__(self, posts: PageQuerySet, link: str, title: str):
self.posts = posts
self.link = link
self._title = title
super().__init__()
def title(self) -> str:
return self._title
def items(self) -> PageQuerySet:
return self.posts
@method_decorator(cache_control(max_age=60 * 60), name="dispatch")
class FaviconView(RedirectView):
def get_redirect_url(self) -> str:

View file

@ -1,24 +1,16 @@
from django.test import TestCase
from django.urls import reverse
from website.blog.factories import BlogPostListPageFactory
from website.home.models import HomePage
class PostsFeedViewTestCase(TestCase):
@classmethod
def setUpTestData(cls) -> None:
cls.home_page = HomePage.objects.get()
cls.page = BlogPostListPageFactory(parent=cls.home_page)
def test_redirects(self) -> None:
response = self.client.get("/posts/index.xml")
self.assertRedirects(
response, self.page.url + self.page.reverse_subpage("feed"), status_code=301
)
class AllPagesFeedViewTestCase(TestCase):
def test_redirects(self) -> None:
response = self.client.get("/index.xml")
self.assertRedirects(response, reverse("feed"), status_code=301)
self.assertRedirects(
response, reverse("feed"), status_code=301, fetch_redirect_response=True
)
def test_redirects_posts(self) -> None:
response = self.client.get("/posts/index.xml")
self.assertRedirects(
response, reverse("feed"), status_code=301, fetch_redirect_response=True
)

View file

@ -5,7 +5,7 @@ from . import views
app_name = "legacy"
urlpatterns = [
path("posts/index.xml", views.PostsFeedView.as_view()),
path("posts/index.xml", views.AllPagesFeedView.as_view()),
path("index.xml", views.AllPagesFeedView.as_view()),
path("tags/<slug:slug>/", views.TagView.as_view()),
path("tags/", views.TagsView.as_view()),

View file

@ -3,16 +3,7 @@ from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_control
from django.views.generic import RedirectView
from website.blog.models import BlogPostListPage, BlogPostTagListPage, BlogPostTagPage
@method_decorator(cache_control(max_age=60 * 60), name="dispatch")
class PostsFeedView(RedirectView):
permanent = True
def get_redirect_url(self) -> str:
post_list = get_object_or_404(BlogPostListPage)
return post_list.url + post_list.reverse_subpage("feed")
from website.blog.models import BlogPostTagListPage, BlogPostTagPage
@method_decorator(cache_control(max_age=60 * 60), name="dispatch")