Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
425 changes: 425 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"avatars:gen": "tsx scripts/avatars.ts",
"members:gen": "tsx scripts/all-members.ts",
"former-members:gen": "tsx scripts/get-former-members.ts",
"search-meta:gen": "tsx scripts/get-search-meta.ts",
"search-meta:gen": "tsx scripts/get-search-meta.ts && npm run blog:rss",
"blog:rss": "tsx scripts/gen-rss.ts",
"contributing:gen": "tsx scripts/build-contributing-page.ts",
"start": "next start",
"cache:clean": "rm -rf .next .contentlayer",
Expand Down Expand Up @@ -41,6 +42,7 @@
"contentlayer": "0.3.0",
"date-fns": "^2.28.0",
"docsearch.js": "^2.6.3",
"feed": "^4.2.2",
"focus-visible": "5.2.0",
"formik": "^2.2.9",
"framer-motion": "9.0.2",
Expand Down
1,032 changes: 1,032 additions & 0 deletions public/blog/atom

Large diffs are not rendered by default.

1,032 changes: 1,032 additions & 0 deletions public/blog/atom.xml

Large diffs are not rendered by default.

703 changes: 703 additions & 0 deletions public/blog/feed.json

Large diffs are not rendered by default.

643 changes: 643 additions & 0 deletions public/blog/rss

Large diffs are not rendered by default.

643 changes: 643 additions & 0 deletions public/blog/rss.xml

Large diffs are not rendered by default.

104 changes: 104 additions & 0 deletions scripts/gen-rss.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import {
parseMarkdownString,
posixPath,
} from '@docusaurus/utils'
import { Feed } from 'feed'
import fs from 'fs'
import path from 'path'
import shell from 'shelljs'
import siteConfig from '../configs/site-config.json'

const websiteRoot = 'content'
const blogRoot = path.join(websiteRoot, 'blog')
const siteUrl = siteConfig.seo.siteUrl

async function getMDXMeta(file: string) {
const markdownString = fs.readFileSync(file).toString()
const { frontMatter: _frontMatter } = await parseMarkdownString(markdownString)
const frontMatter = _frontMatter as any

const filePath = posixPath(file)
const slug = filePath
.replace(posixPath(path.join(process.cwd(), websiteRoot)), '')
.replace('.mdx', '')

return {
title: frontMatter.title,
description: frontMatter.description,
date: new Date(frontMatter.publishedDate),
authors: frontMatter.authors || [],
url: `${siteUrl}${slug}`,
guid: slug,
}
}

async function genRSS() {
const files = shell
.ls('-R', blogRoot)
.map((file) => path.join(process.cwd(), blogRoot, file))
.filter((file) => file.endsWith('.mdx'))

const feed = new Feed({
title: siteConfig.seo.title + ' Blog',
description: siteConfig.seo.description,
id: siteUrl + '/blog',
link: siteUrl + '/blog',
language: 'en',
image: `${siteUrl}/logo.png`,
favicon: `${siteUrl}/favicon.ico`,
copyright: siteConfig.copyright.replace('{{date}}', new Date().getFullYear().toString()),
generator: 'UniKernels RSS Generator',
feedLinks: {
rss2: `${siteUrl}/blog/rss.xml`,
atom: `${siteUrl}/blog/atom.xml`,
},
author: {
name: 'UniKernels',
link: siteUrl,
},
})

const posts = []
for (const file of files) {
try {
const meta = await getMDXMeta(file)
posts.push(meta)
} catch (e) {
console.error(`Error parsing ${file}:`, e)
}
}

// Sort posts by date descending
posts.sort((a, b) => b.date.getTime() - a.date.getTime())

posts.forEach((post) => {
feed.addItem({
title: post.title,
id: post.url,
link: post.url,
description: post.description,
date: post.date,
author: post.authors.map((name: string) => ({ name })),
})
})

// Also include the feeds directly in the public/blog folder
const publicBlogDir = path.join(process.cwd(), 'public', 'blog')
if (!fs.existsSync(publicBlogDir)) {
shell.mkdir('-p', publicBlogDir)
}

fs.writeFileSync(path.join(publicBlogDir, 'rss.xml'), feed.rss2())
fs.writeFileSync(path.join(publicBlogDir, 'atom.xml'), feed.atom1())
fs.writeFileSync(path.join(publicBlogDir, 'feed.json'), feed.json1())

// Additionally, to support /blog/rss and /blog/atom (without extension),
// we can create those files without extensions in the public folder.
// Next.js will serve them from public.
fs.writeFileSync(path.join(publicBlogDir, 'rss'), feed.rss2())
fs.writeFileSync(path.join(publicBlogDir, 'atom'), feed.atom1())

console.log('RSS, Atom and JSON feeds generated successfully! ✅')
}

genRSS()