Add styles to feeds

Copied from https://darekkay.com/blog/rss-styling/
This commit is contained in:
Jake Howard 2023-07-16 14:30:08 +01:00
parent 530503d769
commit c5d04240b1
Signed by: jake
GPG key ID: 57AFB45680EDD477
4 changed files with 35 additions and 6 deletions

View file

@ -23,5 +23,7 @@ mkcontrib fira-code/files node_modules/@fontsource/fira-code/files/fira-code-lat
mkcontrib htmx node_modules/htmx.org/dist/{htmx.min.js,ext} mkcontrib htmx node_modules/htmx.org/dist/{htmx.min.js,ext}
mkcontrib glightbox node_modules/glightbox/dist/css/glightbox.min.css mkcontrib glightbox node_modules/glightbox/dist/css/glightbox.min.css
curl -sf -L https://raw.githubusercontent.com/genmon/aboutfeeds/main/tools/pretty-feed-v3.xsl -o $CONTRIB_DIR/pretty-feed-v3.xsl
# HACK: Make sure Google lighthouse can tell we're using `font-display: swap` # HACK: Make sure Google lighthouse can tell we're using `font-display: swap`
find $CONTRIB_DIR/fira-code -type f -exec sed -i 's/var(--fontsource-display, swap)/swap/g' {} \; find $CONTRIB_DIR/fira-code -type f -exec sed -i 's/var(--fontsource-display, swap)/swap/g' {} \;

View file

@ -85,4 +85,5 @@ class BlogPostListPageTestCase(TestCase):
self.page.url + self.page.reverse_subpage("feed") self.page.url + self.page.reverse_subpage("feed")
) )
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual(response["Content-Type"], "application/rss+xml; charset=utf-8") self.assertEqual(response["Content-Type"], "application/xml")
self.assertContains(response, "xml-stylesheet")

View file

@ -64,4 +64,5 @@ class ListingPageTestCase(TestCase):
self.page.url + self.page.reverse_subpage("feed") self.page.url + self.page.reverse_subpage("feed")
) )
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual(response["Content-Type"], "application/rss+xml; charset=utf-8") self.assertEqual(response["Content-Type"], "application/xml")
self.assertContains(response, "xml-stylesheet")

View file

@ -4,6 +4,7 @@ from typing import Any, Optional
from django.contrib.syndication.views import Feed from django.contrib.syndication.views import Feed
from django.http.request import HttpRequest from django.http.request import HttpRequest
from django.http.response import HttpResponse from django.http.response import HttpResponse
from django.templatetags.static import static
from django.urls import reverse from django.urls import reverse
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_control, cache_page from django.views.decorators.cache import cache_control, cache_page
@ -12,6 +13,7 @@ from django.views.generic import TemplateView
from wagtail.models import Page from wagtail.models import Page
from wagtail.query import PageQuerySet from wagtail.query import PageQuerySet
from website.common.utils import get_site_title
from website.contrib.singleton_page.utils import SingletonPageCache from website.contrib.singleton_page.utils import SingletonPageCache
from website.home.models import HomePage from website.home.models import HomePage
from website.search.models import SearchPage from website.search.models import SearchPage
@ -56,15 +58,35 @@ class KeybaseView(TemplateView):
class AllPagesFeed(Feed): class AllPagesFeed(Feed):
link = "/feed/" link = "/"
title = "All pages feed"
def __init__(self) -> None:
self.style_tag = f'<?xml-stylesheet href="{static("contrib/pretty-feed-v3.xsl")}" type="text/xsl"?>'.encode()
super().__init__()
@method_decorator(cache_page(60 * 60)) @method_decorator(cache_page(60 * 60))
def __call__( def __call__(
self, request: HttpRequest, *args: list, **kwargs: dict self, request: HttpRequest, *args: list, **kwargs: dict
) -> HttpResponse: ) -> HttpResponse:
self.request = request self.request = request
return super().__call__(request, *args, **kwargs) response = super().__call__(request, *args, **kwargs)
# Override Content-Type to allow styles
response.headers["content-type"] = "application/xml"
# Inject styles
opening_xml = response.content.find(b"?>") + 2
response.content = (
response.content[:opening_xml]
+ b"\n"
+ self.style_tag
+ response.content[opening_xml:]
)
return response
def title(self) -> str:
return f"All Pages Feed :: {get_site_title()}"
def items(self) -> PageQuerySet: def items(self) -> PageQuerySet:
return ( return (
@ -109,8 +131,11 @@ class ContentPageFeed(AllPagesFeed):
def __init__(self, posts: PageQuerySet, link: str, title: str): def __init__(self, posts: PageQuerySet, link: str, title: str):
self.posts = posts self.posts = posts
self.link = link self.link = link
self.title = title self._title = title
super().__init__() super().__init__()
def title(self) -> str:
return self._title
def items(self) -> PageQuerySet: def items(self) -> PageQuerySet:
return self.posts return self.posts