notes: new rss feed format

This commit is contained in:
Ivy Turner 2025-05-02 18:14:38 +01:00
parent 5eb24fde8b
commit b13a6a4c5a
No known key found for this signature in database

View file

@ -8,33 +8,48 @@ import { formattedDate } from '~/lib/date';
const parser = new MarkdownIt(); const parser = new MarkdownIt();
/**
* Extract links from HTML and append them as footnotes.
* @param {string} html - The HTML content to process.
* @returns {string} - The plain text content with links as footnotes.
*/
function stripHtmlAndAddFootnotes(html) {
const linkRegex = /<a\s+(?:[^>]*?\s+)?href="([^"]*)">(.*?)<\/a>/g;
let footnotes = [];
let footnoteIndex = 1;
// Replace links with footnote references
const text = html.replace(linkRegex, (match, href, text) => {
footnotes.push(`[${footnoteIndex}]: ${href}`);
return `${text} [${footnoteIndex++}]`;
});
// Strip remaining HTML tags
const plainText = sanitizeHtml(text, { allowedTags: [], allowedAttributes: {} });
// Append footnotes to the content
return `${plainText}\n\n${footnotes.join('\n')}`;
}
export async function GET(context) { export async function GET(context) {
const blog = await getCollection('notes'); const blog = await getCollection('notes');
return rss({ return rss({
// `<title>` field in output xml
title: conf.site.title, title: conf.site.title,
// `<description>` field in output xml
description: conf.site.description, description: conf.site.description,
// Pull in your project "site" from the endpoint context
// https://docs.astro.build/en/reference/api-reference/#site
site: context.site, site: context.site,
stylesheet: "/feed.xsl", // stylesheet: "/feed.xsl",
// Array of `<item>`s in output xml items: blog.map((post) => {
// See "Generating items" section for examples using content collections and glob imports const contentWithFootnotes = stripHtmlAndAddFootnotes(parser.render(post.body));
items: blog.map((post) => ({ return {
title: post.data.title || `A note from ${formattedDate(post.data.date)}`, title: post.data.title || `A note from ${formattedDate(post.data.date)}`,
pubDate: post.data.date, pubDate: post.data.date,
description: post.data.description, description: post.data.description,
// Compute RSS link from post `id` link: `/notes/${post.id}/`,
// This example assumes all posts are rendered as `/blog/[id]` routes trailingSlash: false,
link: `/notes/${post.id}/`, content: contentWithFootnotes,
trailingSlash: false, ...post.data,
content: sanitizeHtml(parser.render(post.body), { };
allowedTags: sanitizeHtml.defaults.allowedTags.concat(['img']) }),
}),
...post.data,
})),
// (optional) inject custom xml
customData: `<language>en-gb</language>`, customData: `<language>en-gb</language>`,
}); });
} }