mirror of
https://github.com/svemagie/blog-eleventy-indiekit.git
synced 2026-04-02 16:44:56 +02:00
feat: add RSS per-category feed template, discovery links, and WebSub notifications
- Create category-feed.njk (RSS 2.0 pagination template) - Add conditional <link rel="alternate"> tags for category pages in base.njk - Extend WebSub hub notifications to include per-category feed URLs
This commit is contained in:
@@ -96,6 +96,10 @@
|
|||||||
{% if site.markdownAgents.enabled and page.url and page.url.startsWith('/articles/') and page.url != '/articles/' %}
|
{% if site.markdownAgents.enabled and page.url and page.url.startsWith('/articles/') and page.url != '/articles/' %}
|
||||||
<link rel="alternate" type="text/markdown" href="{{ page.url | stripTrailingSlash }}.md" title="Markdown version">
|
<link rel="alternate" type="text/markdown" href="{{ page.url | stripTrailingSlash }}.md" title="Markdown version">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if category and page.url and page.url.startsWith('/categories/') and page.url != '/categories/' %}
|
||||||
|
<link rel="alternate" type="application/rss+xml" href="/categories/{{ category | slugify }}/feed.xml" title="{{ category }} — RSS Feed">
|
||||||
|
<link rel="alternate" type="application/json" href="/categories/{{ category | slugify }}/feed.json" title="{{ category }} — JSON Feed">
|
||||||
|
{% endif %}
|
||||||
<link rel="authorization_endpoint" href="{{ site.url }}/auth">
|
<link rel="authorization_endpoint" href="{{ site.url }}/auth">
|
||||||
<link rel="token_endpoint" href="{{ site.url }}/auth/token">
|
<link rel="token_endpoint" href="{{ site.url }}/auth/token">
|
||||||
<link rel="micropub" href="{{ site.url }}/micropub">
|
<link rel="micropub" href="{{ site.url }}/micropub">
|
||||||
|
|||||||
47
category-feed.njk
Normal file
47
category-feed.njk
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
---
|
||||||
|
eleventyExcludeFromCollections: true
|
||||||
|
eleventyImport:
|
||||||
|
collections:
|
||||||
|
- categoryFeeds
|
||||||
|
pagination:
|
||||||
|
data: collections.categoryFeeds
|
||||||
|
size: 1
|
||||||
|
alias: categoryFeed
|
||||||
|
permalink: "categories/{{ categoryFeed.slug }}/feed.xml"
|
||||||
|
---
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
|
||||||
|
<channel>
|
||||||
|
<title>{{ site.name }} — {{ categoryFeed.name }}</title>
|
||||||
|
<link>{{ site.url }}/categories/{{ categoryFeed.slug }}/</link>
|
||||||
|
<description>Posts tagged with "{{ categoryFeed.name }}" on {{ site.name }}</description>
|
||||||
|
<language>{{ site.locale | default('en') }}</language>
|
||||||
|
<atom:link href="{{ site.url }}/categories/{{ categoryFeed.slug }}/feed.xml" rel="self" type="application/rss+xml"/>
|
||||||
|
<atom:link href="https://websubhub.com/hub" rel="hub"/>
|
||||||
|
<lastBuildDate>{{ categoryFeed.posts | getNewestCollectionItemDate | dateToRfc822 }}</lastBuildDate>
|
||||||
|
{%- for post in categoryFeed.posts %}
|
||||||
|
{%- set absolutePostUrl = site.url + post.url %}
|
||||||
|
{%- set postImage = post.data.photo %}
|
||||||
|
{%- if postImage %}
|
||||||
|
{%- if postImage[0] and (postImage[0] | length) > 10 %}
|
||||||
|
{%- set postImage = postImage[0] %}
|
||||||
|
{%- endif %}
|
||||||
|
{%- endif %}
|
||||||
|
{%- if not postImage or postImage == "" %}
|
||||||
|
{%- set postImage = post.data.image or (post.content | extractFirstImage) %}
|
||||||
|
{%- endif %}
|
||||||
|
<item>
|
||||||
|
<title>{{ post.data.title | default(post.content | striptags | truncate(80)) | escape }}</title>
|
||||||
|
<link>{{ absolutePostUrl }}</link>
|
||||||
|
<guid isPermaLink="true">{{ absolutePostUrl }}</guid>
|
||||||
|
<pubDate>{{ post.date | dateToRfc822 }}</pubDate>
|
||||||
|
<description>{{ post.content | htmlToAbsoluteUrls(absolutePostUrl) | escape }}</description>
|
||||||
|
{%- if postImage and postImage != "" and (postImage | length) > 10 %}
|
||||||
|
{%- set imageUrl = postImage | url | absoluteUrl(site.url) %}
|
||||||
|
<enclosure url="{{ imageUrl }}" type="image/jpeg" length="0"/>
|
||||||
|
<media:content url="{{ imageUrl }}" medium="image"/>
|
||||||
|
{%- endif %}
|
||||||
|
</item>
|
||||||
|
{%- endfor %}
|
||||||
|
</channel>
|
||||||
|
</rss>
|
||||||
@@ -908,6 +908,22 @@ export default function (eleventyConfig) {
|
|||||||
`${siteUrl}/feed.xml`,
|
`${siteUrl}/feed.xml`,
|
||||||
`${siteUrl}/feed.json`,
|
`${siteUrl}/feed.json`,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Discover category feed URLs from build output
|
||||||
|
const outputDir = directories?.output || dir.output;
|
||||||
|
const categoriesDir = resolve(outputDir, "categories");
|
||||||
|
try {
|
||||||
|
for (const entry of readdirSync(categoriesDir, { withFileTypes: true })) {
|
||||||
|
if (entry.isDirectory() && existsSync(resolve(categoriesDir, entry.name, "feed.xml"))) {
|
||||||
|
feedUrls.push(`${siteUrl}/categories/${entry.name}/feed.xml`);
|
||||||
|
feedUrls.push(`${siteUrl}/categories/${entry.name}/feed.json`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// categoriesDir may not exist on first build — ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[websub] Notifying hub for ${feedUrls.length} URLs...`);
|
||||||
for (const feedUrl of feedUrls) {
|
for (const feedUrl of feedUrls) {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(hubUrl, {
|
const res = await fetch(hubUrl, {
|
||||||
|
|||||||
Reference in New Issue
Block a user