Skip to content

Commit

Permalink
feat: generate rss feed
Browse files Browse the repository at this point in the history
  • Loading branch information
d-koppenhagen committed Jan 17, 2024
1 parent 937264b commit 705ebc2
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 2 deletions.
26 changes: 24 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"angular-twitter-timeline": "^15.0.0",
"animate.css": "^4.1.1",
"clipboard": "^2.0.11",
"feed": "^4.2.2",
"front-matter": "^4.0.2",
"marked": "^11.1.1",
"marked-gfm-heading-id": "^3.1.0",
Expand Down
90 changes: 90 additions & 0 deletions src/server/routes/rss.xml.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { Feed } from 'feed';
import * as fs from 'fs';
import { defineEventHandler } from 'h3';
import { marked } from 'marked';
import * as path from 'path';
import fm from 'front-matter';
import { PostAttributes } from 'src/app/types';
import { createHash } from 'crypto';

function generateReproducibleHash(input: string): string {
const hash = createHash('md5'); // You can use other algorithms like 'sha256', 'sha1', etc.

// Update the hash with the input data
hash.update(input);

// Generate a hexadecimal digest
const digest = hash.digest('hex');

// Format the digest as a GUID
const formattedGuid = `${digest.substring(0, 8)}-${digest.substring(
8,
12,
)}-${digest.substring(12, 16)}-${digest.substring(16, 20)}-${digest.substring(
20,
)}`;

return formattedGuid;
}

export default defineEventHandler((event) => {
const baseDir = './src/content/blog';
const baseUrl = 'https://k9n.dev';
function generateRssFeed(): string {
const mainFeed = new Feed({
title: 'k9n.dev Blog',
id: `${baseUrl}`, // replace with your site URL
link: `${baseUrl}/api/rss.xml`, // replace with your feed URL
language: 'de',
copyright: '2024 by Danny Koppenhagen',
});

const files = fs.readdirSync(baseDir);
files.forEach((file) => {
const filePath = path.join(baseDir, file);
const fileContent = fs.readFileSync(filePath, 'utf-8');
const frontmatter = fm<PostAttributes>(fileContent);

const content = marked(frontmatter.body) as string;

const headerImage = frontmatter.attributes.thumbnail?.header;
const cardImage = frontmatter.attributes.thumbnail?.header;
let image =
typeof headerImage === 'string'
? headerImage
: typeof cardImage === 'string'
? cardImage
: undefined;
image =
image && /^https?:\/\//i.test(image) ? image : `${baseUrl}/${image}`;
// Add item to the main feed
mainFeed.addItem({
title: frontmatter.attributes.title,
id: generateReproducibleHash(file), // replace with your item URL
link: `${baseUrl}/blog/${file.replace(/\.md$/, '')}`, // replace with your item URL
description: frontmatter.attributes.description,
date: new Date(
frontmatter.attributes.updated || frontmatter.attributes.created,
),
image,
content: content,
author: [
{
name: frontmatter.attributes.author.name,
email: frontmatter.attributes.author.mail,
link: baseUrl,
},
],
published: new Date(frontmatter.attributes.created),
});
});

return mainFeed.rss2();
}

// Output the combined RSS feed as a string
const rssFeedString = generateRssFeed();

event.node.res.setHeader('content-type', 'text/xml');
event.node.res.end(rssFeedString);
});
1 change: 1 addition & 0 deletions vite.config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default defineConfig(({ mode }) => ({
analog({
prerender: {
routes: async () => [
'/api/rss.xml',
'/',
'/blog',
'/contact',
Expand Down

0 comments on commit 705ebc2

Please sign in to comment.