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;
|
@apply overflow-auto rounded-2 p-[1em] font-mono text-code mbe-10 mbs-0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<slot name="rss-writer" />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from 'astro:content';
|
||||||
|
|
||||||
import { formatPosts } from '../utils';
|
import { formatPosts, isProduction, sortMarkdownByDate } from '../utils';
|
||||||
|
|
||||||
import { site, animation, animationDelay } from '../data/site';
|
import { site, animation, animationDelay } from '../data/site';
|
||||||
|
|
||||||
@@ -12,6 +12,13 @@ import PageTitle from '../components/PageTitle.astro';
|
|||||||
import Picture from '../components/Picture.astro';
|
import Picture from '../components/Picture.astro';
|
||||||
import JournalList from '../components/JournalList.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 { Headline } from '../components';
|
||||||
|
|
||||||
import { Content as AboutMe } from '../text/homepage/about-me.mdx';
|
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 title = 'Stefan Imhoff';
|
||||||
const description = 'Front-End Web Developer from Hamburg, Germany';
|
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>
|
<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} />
|
<JournalList entries={formattedLatest} />
|
||||||
</article>
|
</article>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
|
|
||||||
|
<WriteFile slot="rss-writer">
|
||||||
|
<RssXml allPosts={isProduction ? rssPosts : []} slot="rss-writer" />
|
||||||
|
</WriteFile>
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
export const sortByDate = (a: any, b: any) => {
|
export const sortByDate = (a: any, b: any) => {
|
||||||
return Date.parse(b.data.date.toISOString()) - Date.parse(a.data.date.toISOString());
|
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