2023-07-16 18:52:51 +08:00
import { writeFileSync , mkdirSync } from 'fs'
import path from 'path'
2024-01-28 11:28:05 +08:00
import { slug } from 'github-slugger'
2023-07-23 23:06:10 +08:00
import { escape } from 'pliny/utils/htmlEscaper.js'
2023-07-07 11:17:22 +08:00
import siteMetadata from '../data/siteMetadata.js'
2024-11-04 23:00:40 -06:00
// Do not accept changes from upstream, you need with instead of assert. See https://stackoverflow.com/questions/78876691/syntaxerror-unexpected-identifier-assert-on-json-import-in-node-v22
import tagData from '../app/tag-data.json' with { type : 'json' }
2023-07-07 11:17:22 +08:00
import { allBlogs } from '../.contentlayer/generated/index.mjs'
2023-10-12 01:01:29 +08:00
import { sortPosts } from 'pliny/utils/contentlayer.js'
2023-07-07 11:17:22 +08:00
2024-10-17 22:20:36 +08:00
const outputFolder = process . env . EXPORT ? 'out' : 'public'
2023-07-16 18:52:51 +08:00
const generateRssItem = ( config , post ) => `
< item >
< guid > $ { config . siteUrl } / blog / $ { post . slug } < / g u i d >
< title > $ { escape ( post . title ) } < / t i t l e >
< link > $ { config . siteUrl } / blog / $ { post . slug } < / l i n k >
$ { post . summary && ` <description> ${ escape ( post . summary ) } </description> ` }
< pubDate > $ { new Date ( post . date ) . toUTCString ( ) } < / p u b D a t e >
< author > $ { config . email } ( $ { config . author } ) < / a u t h o r >
$ { post . tags && post . tags . map ( ( t ) => ` <category> ${ t } </category> ` ) . join ( '' ) }
< / i t e m >
`
const generateRss = ( config , posts , page = 'feed.xml' ) => `
< rss version = "2.0" xmlns : atom = "http://www.w3.org/2005/Atom" >
< channel >
< title > $ { escape ( config . title ) } < / t i t l e >
< link > $ { config . siteUrl } / blog < / l i n k >
< description > $ { escape ( config . description ) } < / d e s c r i p t i o n >
< language > $ { config . language } < / l a n g u a g e >
< managingEditor > $ { config . email } ( $ { config . author } ) < / m a n a g i n g E d i t o r >
< webMaster > $ { config . email } ( $ { config . author } ) < / w e b M a s t e r >
< lastBuildDate > $ { new Date ( posts [ 0 ] . date ) . toUTCString ( ) } < / l a s t B u i l d D a t e >
< atom : link href = "${config.siteUrl}/${page}" rel = "self" type = "application/rss+xml" / >
$ { posts . map ( ( post ) => generateRssItem ( config , post ) ) . join ( '' ) }
< / c h a n n e l >
< / r s s >
`
2023-07-23 23:01:00 +08:00
async function generateRSS ( config , allBlogs , page = 'feed.xml' ) {
2023-07-16 18:52:51 +08:00
const publishPosts = allBlogs . filter ( ( post ) => post . draft !== true )
// RSS for blog post
if ( publishPosts . length > 0 ) {
2023-10-12 01:01:29 +08:00
const rss = generateRss ( config , sortPosts ( publishPosts ) )
2024-10-17 22:20:36 +08:00
writeFileSync ( ` ./ ${ outputFolder } / ${ page } ` , rss )
2023-07-16 18:52:51 +08:00
}
if ( publishPosts . length > 0 ) {
for ( const tag of Object . keys ( tagData ) ) {
2024-10-31 22:37:40 +08:00
const filteredPosts = allBlogs . filter ( ( post ) => post . tags . map ( ( t ) => slug ( t ) ) . includes ( tag ) )
2023-07-23 23:01:00 +08:00
const rss = generateRss ( config , filteredPosts , ` tags/ ${ tag } / ${ page } ` )
2024-10-17 22:20:36 +08:00
const rssPath = path . join ( outputFolder , 'tags' , tag )
2023-07-16 18:52:51 +08:00
mkdirSync ( rssPath , { recursive : true } )
2023-07-23 23:01:00 +08:00
writeFileSync ( path . join ( rssPath , page ) , rss )
2023-07-16 18:52:51 +08:00
}
}
}
2023-07-07 11:17:22 +08:00
const rss = ( ) => {
generateRSS ( siteMetadata , allBlogs )
console . log ( 'RSS feed generated...' )
}
export default rss