From f3986f9d6c7461d8bdd559604b5bf13b8f538b67 Mon Sep 17 00:00:00 2001 From: Stefan Imhoff Date: Tue, 13 Jun 2023 18:52:13 +0200 Subject: [PATCH] feat: implement hack for journal post RSS feed Astro is currently not able to render the compiled HTML of MDX files to a string. This makes it impossible to render the content for an RSS feed. Issue: Container API: render components in isolation https://github.com/withastro/roadmap/issues/533 Proposal: MDX compiledContent() support https://github.com/withastro/roadmap/discussions/419 To still be able to have full content for RSS feeds, this dirty hack, Scott Willsey writes about in his 2-part blog post is needed: https://scottwillsey.com/rss-pt1/ https://scottwillsey.com/rss-pt2/ --- src/components/RssXml.astro | 41 ++++++++++++++++++++++++++++++++++ src/components/WriteFile.astro | 13 +++++++++++ src/layouts/BaseLayout.astro | 1 + src/pages/index.astro | 16 ++++++++++++- src/utils/sort-by-date.ts | 4 ++++ 5 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/components/RssXml.astro create mode 100644 src/components/WriteFile.astro diff --git a/src/components/RssXml.astro b/src/components/RssXml.astro new file mode 100644 index 0000000..8dea823 --- /dev/null +++ b/src/components/RssXml.astro @@ -0,0 +1,41 @@ +--- +import { site } from '../data/site'; +import { dateToISO } from '../utils'; + +import { mapping } from '../mdx-components'; + +const { allPosts } = Astro.props; +const rssHeaderXml = ` + + + ${site.title} + + ${site.url}`; + +const rssFooterXml = ` +`; +--- + + +{ + allPosts.map((post: any) => ( + <> + + ${post.frontmatter.title} + ${`${site.url}/${post.frontmatter.slug}/`} + ${`${site.url}/${post.frontmatter.slug}/`} + + ${dateToISO(post.frontmatter.date)} + + + + +`} + /> + + )) +} + diff --git a/src/components/WriteFile.astro b/src/components/WriteFile.astro new file mode 100644 index 0000000..6fdf974 --- /dev/null +++ b/src/components/WriteFile.astro @@ -0,0 +1,13 @@ +--- +import path from 'node:path'; +import fs from 'node:fs/promises'; + +const distFolder = './dist'; +const filename = 'rss.xml'; +const fileUrl = path.join(distFolder, filename); + +if (Astro.slots.has('rss-writer')) { + const html = await Astro.slots.render('rss-writer'); + await fs.writeFile(fileUrl, html); +} +--- diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 6dea900..fd3b535 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -178,5 +178,6 @@ const webManifest = isProduction && { @apply overflow-auto rounded-2 p-[1em] font-mono text-code mbe-10 mbs-0; } + diff --git a/src/pages/index.astro b/src/pages/index.astro index 1f5e127..c2b695a 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,7 +1,7 @@ --- import { getCollection } from 'astro:content'; -import { formatPosts } from '../utils'; +import { formatPosts, isProduction, sortMarkdownByDate } from '../utils'; import { site, animation, animationDelay } from '../data/site'; @@ -12,6 +12,13 @@ import PageTitle from '../components/PageTitle.astro'; import Picture from '../components/Picture.astro'; import JournalList from '../components/JournalList.astro'; +/* FIXME: Remove hack as soon as this issue is resolved: + * Issue: https://github.com/withastro/roadmap/issues/533 + * Proposal: https://github.com/withastro/roadmap/discussions/419 + */ +import WriteFile from '../components/WriteFile.astro'; +import RssXml from '../components/RssXml.astro'; + import { Headline } from '../components'; import { Content as AboutMe } from '../text/homepage/about-me.mdx'; @@ -25,6 +32,9 @@ const formattedLatest = formatPosts(allPosts, { limit: 6 }); const title = 'Stefan Imhoff'; const description = 'Front-End Web Developer from Hamburg, Germany'; + +const rssPosts = await Astro.glob('../content/journal/**/*.mdx'); +rssPosts.sort(sortMarkdownByDate); --- @@ -81,3 +91,7 @@ const description = 'Front-End Web Developer from Hamburg, Germany'; + + + + diff --git a/src/utils/sort-by-date.ts b/src/utils/sort-by-date.ts index 8ace8d4..093665d 100644 --- a/src/utils/sort-by-date.ts +++ b/src/utils/sort-by-date.ts @@ -1,3 +1,7 @@ export const sortByDate = (a: any, b: any) => { return Date.parse(b.data.date.toISOString()) - Date.parse(a.data.date.toISOString()); }; + +export const sortMarkdownByDate = (a: any, b: any) => { + return Date.parse(b.frontmatter.date) - Date.parse(a.frontmatter.date); +};