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:
parent
aa5107c89e
commit
e5ae66567a
8 changed files with 27 additions and 83 deletions
|
@ -1,4 +1,5 @@
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
from website.home.models import HomePage
|
from website.home.models import HomePage
|
||||||
|
|
||||||
|
@ -73,17 +74,13 @@ class BlogPostListPageTestCase(TestCase):
|
||||||
response = self.client.get(self.page.url)
|
response = self.client.get(self.page.url)
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertEqual(len(response.context["listing_pages"]), 2)
|
self.assertEqual(len(response.context["listing_pages"]), 2)
|
||||||
self.assertContains(response, self.page.reverse_subpage("feed"))
|
|
||||||
|
|
||||||
def test_queries(self) -> None:
|
def test_queries(self) -> None:
|
||||||
with self.assertNumQueries(44):
|
with self.assertNumQueries(44):
|
||||||
self.client.get(self.page.url)
|
self.client.get(self.page.url)
|
||||||
|
|
||||||
def test_feed_accessible(self) -> None:
|
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.assertRedirects(
|
||||||
self.page.url + self.page.reverse_subpage("feed")
|
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")
|
|
||||||
|
|
|
@ -1,19 +1,17 @@
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from typing import Any, Optional, Type
|
from typing import Any, Optional
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
|
|
||||||
from django.contrib.humanize.templatetags.humanize import NaturalTimeFormatter
|
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 EmptyPage, Paginator
|
||||||
from django.core.paginator import Page as PaginatorPage
|
from django.core.paginator import Page as PaginatorPage
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.http.request import HttpRequest
|
from django.http.request import HttpRequest
|
||||||
from django.http.response import Http404, HttpResponse, HttpResponseBadRequest
|
from django.http.response import Http404, HttpResponse, HttpResponseBadRequest
|
||||||
|
from django.shortcuts import redirect
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.decorators import method_decorator
|
|
||||||
from django.utils.functional import cached_property, classproperty
|
from django.utils.functional import cached_property, classproperty
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
from django.views.decorators.cache import cache_page
|
|
||||||
from wagtail.admin.panels import FieldPanel, MultiFieldPanel
|
from wagtail.admin.panels import FieldPanel, MultiFieldPanel
|
||||||
from wagtail.contrib.routable_page.models import RoutablePageMixin, route
|
from wagtail.contrib.routable_page.models import RoutablePageMixin, route
|
||||||
from wagtail.contrib.settings.models import BaseGenericSetting, register_setting
|
from wagtail.contrib.settings.models import BaseGenericSetting, register_setting
|
||||||
|
@ -257,12 +255,6 @@ class BaseListingPage(RoutablePageMixin, BaseContentPage):
|
||||||
def show_reading_time(self) -> bool:
|
def show_reading_time(self) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@property
|
|
||||||
def feed_class(self) -> Type[Feed]:
|
|
||||||
from .views import ContentPageFeed
|
|
||||||
|
|
||||||
return ContentPageFeed
|
|
||||||
|
|
||||||
@route(r"^$")
|
@route(r"^$")
|
||||||
def index_route(self, request: HttpRequest) -> HttpResponse:
|
def index_route(self, request: HttpRequest) -> HttpResponse:
|
||||||
self.serializer = PaginationSerializer(data=request.GET)
|
self.serializer = PaginationSerializer(data=request.GET)
|
||||||
|
@ -283,13 +275,8 @@ class BaseListingPage(RoutablePageMixin, BaseContentPage):
|
||||||
return url + "?" + urlencode(query_data)
|
return url + "?" + urlencode(query_data)
|
||||||
|
|
||||||
@route(r"^feed/$")
|
@route(r"^feed/$")
|
||||||
@method_decorator(cache_page(60 * 30))
|
|
||||||
def feed(self, request: HttpRequest) -> HttpResponse:
|
def feed(self, request: HttpRequest) -> HttpResponse:
|
||||||
return self.feed_class(
|
return redirect("feed", permanent=True)
|
||||||
self.get_listing_pages(),
|
|
||||||
self.get_full_url(request),
|
|
||||||
self.html_title_tag,
|
|
||||||
)(request)
|
|
||||||
|
|
||||||
|
|
||||||
class ListingPage(BaseListingPage):
|
class ListingPage(BaseListingPage):
|
||||||
|
|
|
@ -1,15 +1,8 @@
|
||||||
{% extends "common/content_page.html" %}
|
{% extends "common/content_page.html" %}
|
||||||
|
|
||||||
{% load wagtailroutablepage_tags wagtailadmin_tags %}
|
{% load wagtailadmin_tags %}
|
||||||
|
|
||||||
{% block extra_head %}
|
|
||||||
{{ block.super }}
|
|
||||||
<link rel="alternate" type="application/rss+xml" href="{% routablepageurl page 'feed' %}" />
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block hero_buttons %}
|
{% 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 %}
|
{% 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>
|
<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 %}
|
{% endif %}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from django.template.loader import get_template
|
from django.template.loader import get_template
|
||||||
from django.test import SimpleTestCase, TestCase
|
from django.test import SimpleTestCase, TestCase
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
from website.common.factories import ContentPageFactory, ListingPageFactory
|
from website.common.factories import ContentPageFactory, ListingPageFactory
|
||||||
from website.common.models import BaseListingPage, BasePage
|
from website.common.models import BaseListingPage, BasePage
|
||||||
|
@ -58,14 +59,11 @@ class ListingPageTestCase(TestCase):
|
||||||
self.assertEqual(len(response.context["listing_pages"]), 2)
|
self.assertEqual(len(response.context["listing_pages"]), 2)
|
||||||
self.assertContains(response, self.page.reverse_subpage("feed"))
|
self.assertContains(response, self.page.reverse_subpage("feed"))
|
||||||
|
|
||||||
def test_feed_accessible(self) -> None:
|
def test_feed_redirects(self) -> None:
|
||||||
with self.assertNumQueries(13):
|
response = self.client.get(self.page.url + self.page.reverse_subpage("feed"))
|
||||||
response = self.client.get(
|
self.assertRedirects(
|
||||||
self.page.url + self.page.reverse_subpage("feed")
|
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:
|
def test_meta_url(self) -> None:
|
||||||
response = self.client.get(self.page.url)
|
response = self.client.get(self.page.url)
|
||||||
|
|
|
@ -93,7 +93,7 @@ class AllPagesFeed(Feed):
|
||||||
return {**super().feed_extra_kwargs(obj), "request": self.request}
|
return {**super().feed_extra_kwargs(obj), "request": self.request}
|
||||||
|
|
||||||
def title(self) -> str:
|
def title(self) -> str:
|
||||||
return f"All Pages Feed :: {get_site_title()}"
|
return f"Feed :: {get_site_title()}"
|
||||||
|
|
||||||
def items(self) -> PageQuerySet:
|
def items(self) -> PageQuerySet:
|
||||||
return (
|
return (
|
||||||
|
@ -149,20 +149,6 @@ class AllPagesFeed(Feed):
|
||||||
item_enclosure_length = 0
|
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")
|
@method_decorator(cache_control(max_age=60 * 60), name="dispatch")
|
||||||
class FaviconView(RedirectView):
|
class FaviconView(RedirectView):
|
||||||
def get_redirect_url(self) -> str:
|
def get_redirect_url(self) -> str:
|
||||||
|
|
|
@ -1,24 +1,16 @@
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.urls import reverse
|
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):
|
class AllPagesFeedViewTestCase(TestCase):
|
||||||
def test_redirects(self) -> None:
|
def test_redirects(self) -> None:
|
||||||
response = self.client.get("/index.xml")
|
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
|
||||||
|
)
|
||||||
|
|
|
@ -5,7 +5,7 @@ from . import views
|
||||||
app_name = "legacy"
|
app_name = "legacy"
|
||||||
|
|
||||||
urlpatterns = [
|
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("index.xml", views.AllPagesFeedView.as_view()),
|
||||||
path("tags/<slug:slug>/", views.TagView.as_view()),
|
path("tags/<slug:slug>/", views.TagView.as_view()),
|
||||||
path("tags/", views.TagsView.as_view()),
|
path("tags/", views.TagsView.as_view()),
|
||||||
|
|
|
@ -3,16 +3,7 @@ from django.utils.decorators import method_decorator
|
||||||
from django.views.decorators.cache import cache_control
|
from django.views.decorators.cache import cache_control
|
||||||
from django.views.generic import RedirectView
|
from django.views.generic import RedirectView
|
||||||
|
|
||||||
from website.blog.models import BlogPostListPage, BlogPostTagListPage, BlogPostTagPage
|
from website.blog.models import 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")
|
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(cache_control(max_age=60 * 60), name="dispatch")
|
@method_decorator(cache_control(max_age=60 * 60), name="dispatch")
|
||||||
|
|
Loading…
Reference in a new issue