mirror of
https://github.com/kogakure/website-astro-stefanimhoff.de.git
synced 2026-02-03 20:15:27 +00:00
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/
This commit is contained in:
41
src/components/RssXml.astro
Normal file
41
src/components/RssXml.astro
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
import { site } from '../data/site';
|
||||
import { dateToISO } from '../utils';
|
||||
|
||||
import { mapping } from '../mdx-components';
|
||||
|
||||
const { allPosts } = Astro.props;
|
||||
const rssHeaderXml = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
|
||||
<channel>
|
||||
<title>${site.title}</title>
|
||||
<description><![CDATA[ ${site.description} ]]></description>
|
||||
<link>${site.url}</link>`;
|
||||
|
||||
const rssFooterXml = ` </channel>
|
||||
</rss>`;
|
||||
---
|
||||
|
||||
<Fragment set:html={rssHeaderXml} />
|
||||
{
|
||||
allPosts.map((post: any) => (
|
||||
<>
|
||||
<Fragment
|
||||
set:html={` <item>
|
||||
<title>${post.frontmatter.title}</title>
|
||||
<link>${`${site.url}/${post.frontmatter.slug}/`}</link>
|
||||
<guid>${`${site.url}/${post.frontmatter.slug}/`}</guid>
|
||||
<description><![CDATA[${post.frontmatter.description}]]></description>
|
||||
<pubDate>${dateToISO(post.frontmatter.date)}</pubDate>
|
||||
<content:encoded><![CDATA[`}
|
||||
/>
|
||||
<post.Content components={mapping} />
|
||||
<Fragment
|
||||
set:html={`]]></content:encoded>
|
||||
</item>
|
||||
`}
|
||||
/>
|
||||
</>
|
||||
))
|
||||
}
|
||||
<Fragment set:html={rssFooterXml} />
|
||||
13
src/components/WriteFile.astro
Normal file
13
src/components/WriteFile.astro
Normal file
@@ -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);
|
||||
}
|
||||
---
|
||||
@@ -178,5 +178,6 @@ const webManifest = isProduction && {
|
||||
@apply overflow-auto rounded-2 p-[1em] font-mono text-code mbe-10 mbs-0;
|
||||
}
|
||||
</style>
|
||||
<slot name="rss-writer" />
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -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);
|
||||
---
|
||||
|
||||
<GridLayout title={title} description={description} grid="fullsize" class="grid" innerGrid>
|
||||
@@ -81,3 +91,7 @@ const description = 'Front-End Web Developer from Hamburg, Germany';
|
||||
<JournalList entries={formattedLatest} />
|
||||
</article>
|
||||
</GridLayout>
|
||||
|
||||
<WriteFile slot="rss-writer">
|
||||
<RssXml allPosts={isProduction ? rssPosts : []} slot="rss-writer" />
|
||||
</WriteFile>
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user