feat: add RSS feed

This commit is contained in:
Kim, Jimin 2025-01-20 20:21:01 +09:00
parent 06fa0502ae
commit 80b6656e38
Signed by: pomp
GPG key ID: 2B516173EDD492EB
9 changed files with 84 additions and 4 deletions

View file

@ -1,4 +1,5 @@
public/robots.txt public/robots.txt
public/rss.xml
public/sitemap*.xml public/sitemap*.xml
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

View file

@ -6,7 +6,7 @@
"dev": "open-cli http://localhost:3000 && pnpm dev:headless", "dev": "open-cli http://localhost:3000 && pnpm dev:headless",
"dev:headless": "next dev", "dev:headless": "next dev",
"build": "next build", "build": "next build",
"postbuild": "next-sitemap", "postbuild": "next-sitemap && cp ../../packages/content/dist/rss.xml public/rss.xml",
"lint": "next lint", "lint": "next lint",
"test:e2e": "playwright test", "test:e2e": "playwright test",
"i_am_sure_i_want_to_nuke_gitignored_files": "rm -rf .next .turbo build node_modules test-results" "i_am_sure_i_want_to_nuke_gitignored_files": "rm -rf .next .turbo build node_modules test-results"

View file

@ -1,4 +1,6 @@
import GithubLinkIcon from "../GithubLinkIcon" import GithubLinkIcon from "../GithubLinkIcon"
import { faRss } from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
export default function Footer() { export default function Footer() {
return ( return (
@ -7,7 +9,15 @@ export default function Footer() {
<div> <div>
Created by <b>developomp</b> Created by <b>developomp</b>
</div> </div>
<GithubLinkIcon href="https://github.com/developomp/developomp-site" /> <div className="flex items-center gap-2">
<a
href="/rss.xml"
className="text-3xl text-light-footer-text transition-colors duration-75 hover:text-light-text-high-contrast dark:text-dark-footer-text dark:hover:text-dark-text-high-contrast"
>
<FontAwesomeIcon icon={faRss} />
</a>
<GithubLinkIcon href="https://github.com/developomp/developomp-site" />
</div>
</div> </div>
</footer> </footer>
) )

View file

@ -9,7 +9,7 @@ interface Props {
export default function GithubLinkIcon({ href }: Props) { export default function GithubLinkIcon({ href }: Props) {
return ( return (
<Link <Link
className="text-5xl text-light-footer-text transition-colors duration-75 hover:text-light-text-high-contrast dark:text-dark-footer-text dark:hover:text-dark-text-high-contrast" className="text-4xl text-light-footer-text transition-colors duration-75 hover:text-light-text-high-contrast dark:text-dark-footer-text dark:hover:text-dark-text-high-contrast"
href={href} href={href}
target="_blank" target="_blank"
aria-label="GitHub link" aria-label="GitHub link"

View file

@ -18,6 +18,7 @@
"@types/markdown-it": "^14.0.1", "@types/markdown-it": "^14.0.1",
"@types/node": "^20.10.5", "@types/node": "^20.10.5",
"@types/read-time-estimate": "^0.0.2", "@types/read-time-estimate": "^0.0.2",
"@types/rss": "^0.0.32",
"@types/tinycolor2": "^1.4.6", "@types/tinycolor2": "^1.4.6",
"elasticlunr": "^0.9.5", "elasticlunr": "^0.9.5",
"eslint": "^8.56.0", "eslint": "^8.56.0",
@ -41,6 +42,7 @@
"remark-parse": "^11.0.0", "remark-parse": "^11.0.0",
"remark-rehype": "^11.1.0", "remark-rehype": "^11.1.0",
"remark-supersub": "^1.0.0", "remark-supersub": "^1.0.0",
"rss": "^1.2.2",
"simple-icons": "^11.13.0", "simple-icons": "^11.13.0",
"tinycolor2": "^1.6.0", "tinycolor2": "^1.6.0",
"tsup": "^8.0.2", "tsup": "^8.0.2",

View file

@ -3,4 +3,5 @@ export const outPath = "./dist" // path to the json database
export const contentDirectoryPath = `${outPath}/content` export const contentDirectoryPath = `${outPath}/content`
export const mapFilePath = `${outPath}/map.json` export const mapFilePath = `${outPath}/map.json`
export const rssFilePath = `${outPath}/rss.xml`
export const searchIndexFilePath = `${outPath}/search.json` export const searchIndexFilePath = `${outPath}/search.json`

View file

@ -8,9 +8,10 @@
import fs from "fs" import fs from "fs"
import { mapFilePath, markdownPath, outPath } from "./config" import { mapFilePath, markdownPath, outPath, rssFilePath } from "./config"
import { fillTags, parseSeries, sortDates } from "./postProcess" import { fillTags, parseSeries, sortDates } from "./postProcess"
import { recursiveParse } from "./recursiveParse" import { recursiveParse } from "./recursiveParse"
import { buildFeed } from "./rss"
import { saveIndex } from "./searchIndex" import { saveIndex } from "./searchIndex"
import type { ContentMap, SeriesMap } from "./types/types" import type { ContentMap, SeriesMap } from "./types/types"
import { ParseMode } from "./types/types" import { ParseMode } from "./types/types"
@ -66,6 +67,7 @@ async function main() {
*/ */
fs.writeFileSync(mapFilePath, JSON.stringify(contentMap)) fs.writeFileSync(mapFilePath, JSON.stringify(contentMap))
fs.writeFileSync(rssFilePath, buildFeed(contentMap))
saveIndex() saveIndex()
} }

View file

@ -0,0 +1,26 @@
import RSS from "rss"
import type { ContentMap } from "./types/types"
export function buildFeed(contentMap: ContentMap): string {
/* lets create an rss feed */
const feed = new RSS({
title: "pomp's blog",
description: "developomp's blog",
feed_url: "https://blog.developomp.com/rss.xml",
site_url: "https://blog.developomp.com",
image_url: "https://blog.developomp.com/favicon.svg",
language: "en",
pubDate: "May 20, 2012 04:00:00 GMT",
})
for (const key in contentMap.posts)
feed.item({
title: contentMap.posts[key].title,
description: contentMap.posts[key].title,
url: `https://blog.developomp.com${key}`,
date: contentMap.posts[key].date,
})
return feed.xml()
}

38
pnpm-lock.yaml generated
View file

@ -290,6 +290,9 @@ importers:
'@types/read-time-estimate': '@types/read-time-estimate':
specifier: ^0.0.2 specifier: ^0.0.2
version: 0.0.2 version: 0.0.2
'@types/rss':
specifier: ^0.0.32
version: 0.0.32
'@types/tinycolor2': '@types/tinycolor2':
specifier: ^1.4.6 specifier: ^1.4.6
version: 1.4.6 version: 1.4.6
@ -359,6 +362,9 @@ importers:
remark-supersub: remark-supersub:
specifier: ^1.0.0 specifier: ^1.0.0
version: 1.0.0 version: 1.0.0
rss:
specifier: ^1.2.2
version: 1.2.2
simple-icons: simple-icons:
specifier: ^11.13.0 specifier: ^11.13.0
version: 11.13.0 version: 11.13.0
@ -1472,6 +1478,9 @@ packages:
'@types/read-time-estimate@0.0.2': '@types/read-time-estimate@0.0.2':
resolution: {integrity: sha512-e0X5M491QQN0vpF97n0NVn4zUhjT6Xi5REi/8ZadZRpFlDV5YHvV6N/F5Vqe553scqgRIARVqaLW9BXoh1Ld7Q==} resolution: {integrity: sha512-e0X5M491QQN0vpF97n0NVn4zUhjT6Xi5REi/8ZadZRpFlDV5YHvV6N/F5Vqe553scqgRIARVqaLW9BXoh1Ld7Q==}
'@types/rss@0.0.32':
resolution: {integrity: sha512-2oKNqKyUY4RSdvl5eZR1n2Q9yvw3XTe3mQHsFPn9alaNBxfPnbXBtGP8R0SV8pK1PrVnLul0zx7izbm5/gF5Qw==}
'@types/semver@7.5.0': '@types/semver@7.5.0':
resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==}
@ -3596,10 +3605,18 @@ packages:
resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
engines: {node: '>=8.6'} engines: {node: '>=8.6'}
mime-db@1.25.0:
resolution: {integrity: sha512-5k547tI4Cy+Lddr/hdjNbBEWBwSl8EBc5aSdKvedav8DReADgWJzcYiktaRIw3GtGC1jjwldXtTzvqJZmtvC7w==}
engines: {node: '>= 0.6'}
mime-db@1.52.0: mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
mime-types@2.1.13:
resolution: {integrity: sha512-ryBDp1Z/6X90UvjUK3RksH0IBPM137T7cmg4OgD5wQBojlAiUwuok0QeELkim/72EtcYuNlmbkrcGuxj3Kl0YQ==}
engines: {node: '>= 0.6'}
mime-types@2.1.35: mime-types@2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
@ -4265,6 +4282,9 @@ packages:
rrweb-cssom@0.6.0: rrweb-cssom@0.6.0:
resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==} resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==}
rss@1.2.2:
resolution: {integrity: sha512-xUhRTgslHeCBeHAqaWSbOYTydN2f0tAzNXvzh3stjz7QDhQMzdgHf3pfgNIngeytQflrFPfy6axHilTETr6gDg==}
run-applescript@7.0.0: run-applescript@7.0.0:
resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==}
engines: {node: '>=18'} engines: {node: '>=18'}
@ -5084,6 +5104,9 @@ packages:
resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
engines: {node: '>=18'} engines: {node: '>=18'}
xml@1.0.1:
resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==}
xmlchars@2.2.0: xmlchars@2.2.0:
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
@ -6183,6 +6206,8 @@ snapshots:
'@types/read-time-estimate@0.0.2': {} '@types/read-time-estimate@0.0.2': {}
'@types/rss@0.0.32': {}
'@types/semver@7.5.0': {} '@types/semver@7.5.0': {}
'@types/stack-utils@2.0.1': {} '@types/stack-utils@2.0.1': {}
@ -9015,8 +9040,14 @@ snapshots:
braces: 3.0.2 braces: 3.0.2
picomatch: 2.3.1 picomatch: 2.3.1
mime-db@1.25.0: {}
mime-db@1.52.0: {} mime-db@1.52.0: {}
mime-types@2.1.13:
dependencies:
mime-db: 1.25.0
mime-types@2.1.35: mime-types@2.1.35:
dependencies: dependencies:
mime-db: 1.52.0 mime-db: 1.52.0
@ -9730,6 +9761,11 @@ snapshots:
rrweb-cssom@0.6.0: {} rrweb-cssom@0.6.0: {}
rss@1.2.2:
dependencies:
mime-types: 2.1.13
xml: 1.0.1
run-applescript@7.0.0: {} run-applescript@7.0.0: {}
run-parallel@1.2.0: run-parallel@1.2.0:
@ -10611,6 +10647,8 @@ snapshots:
xml-name-validator@5.0.0: {} xml-name-validator@5.0.0: {}
xml@1.0.1: {}
xmlchars@2.2.0: {} xmlchars@2.2.0: {}
xtend@4.0.2: {} xtend@4.0.2: {}