mirror of
https://github.com/ipfs/ipfs-blog.git
synced 2026-03-28 17:32:37 +01:00
- add ecosystem content entry linking to ipshipyard.com blog post - support description field in RSS feed entries
97 lines
3.2 KiB
JavaScript
97 lines
3.2 KiB
JavaScript
'use strict'
|
|
|
|
/**
|
|
* Enhances the RSS feed to include items from special content pages
|
|
* (release notes, ecosystem content, etc.) that are stored as YAML
|
|
* arrays in frontmatter rather than individual markdown files.
|
|
*/
|
|
|
|
const fs = require('fs')
|
|
const path = require('path')
|
|
const xml2js = require('xml2js')
|
|
const matter = require('gray-matter')
|
|
const dayjs = require('dayjs')
|
|
|
|
const xmlFilePath = 'dist/index.xml'
|
|
|
|
// Only include items published after this date (to avoid backfilling old content)
|
|
const CUTOFF_DATE = dayjs('2025-11-25')
|
|
|
|
// Content types to include in the unified feed
|
|
// Each item in the data array should have: title, date, path (URL)
|
|
const CONTENT_SOURCES = [
|
|
{ file: 'releasenotes.md', category: 'Release Notes' },
|
|
{ file: 'ecosystemcontent.md', category: 'Ecosystem' },
|
|
{ file: 'newscoverage.md', category: 'News Coverage' },
|
|
{ file: 'videos.md', category: 'Videos' },
|
|
{ file: 'tutorials.md', category: 'Tutorials' },
|
|
{ file: 'events.md', category: 'Events' },
|
|
]
|
|
|
|
function parseContentFile(filename) {
|
|
const filepath = path.resolve('src/_blog', filename)
|
|
try {
|
|
const content = fs.readFileSync(filepath, 'utf8')
|
|
const { data } = matter(content)
|
|
const now = dayjs()
|
|
return (data.data || []).filter((item) => {
|
|
if (item.hidden) return false
|
|
if (item.publish_date && dayjs(item.publish_date).isAfter(now)) return false
|
|
return dayjs(item.publish_date || item.date).isAfter(CUTOFF_DATE)
|
|
})
|
|
} catch (err) {
|
|
console.error(`Warning: Could not read ${filename}:`, err.message)
|
|
return []
|
|
}
|
|
}
|
|
|
|
function itemToRssEntry(item, category) {
|
|
return {
|
|
title: [item.title],
|
|
link: [item.path],
|
|
pubDate: [dayjs(item.date).toDate().toUTCString()],
|
|
description: [item.description || item.title],
|
|
category: [category],
|
|
guid: [{ _: item.path, $: { isPermaLink: 'true' } }],
|
|
}
|
|
}
|
|
|
|
async function enhanceFeed() {
|
|
let xmlData, parsed
|
|
try {
|
|
xmlData = fs.readFileSync(xmlFilePath, 'utf8')
|
|
parsed = await xml2js.parseStringPromise(xmlData)
|
|
} catch (err) {
|
|
console.error('Could not read/parse RSS feed:', err.message)
|
|
process.exit(1)
|
|
}
|
|
|
|
// Blog posts link to the blog domain, special content links externally
|
|
const blogDomain = parsed.rss.channel[0].link[0]
|
|
const existingItems = (parsed.rss.channel[0].item || []).filter(
|
|
(item) => item.link[0].startsWith(blogDomain)
|
|
)
|
|
|
|
// Parse special content and convert to RSS items
|
|
const additionalItems = CONTENT_SOURCES.flatMap((source) =>
|
|
parseContentFile(source.file).map((i) => itemToRssEntry(i, source.category))
|
|
)
|
|
|
|
// Deduplicate by guid
|
|
const seen = new Set()
|
|
const allItems = [...existingItems, ...additionalItems]
|
|
.filter((item) => {
|
|
const guid = item.guid?.[0]?._ || item.guid?.[0] || item.link[0]
|
|
return !seen.has(guid) && seen.add(guid)
|
|
})
|
|
.sort((a, b) => new Date(b.pubDate[0]) - new Date(a.pubDate[0]))
|
|
|
|
parsed.rss.channel[0].item = allItems
|
|
|
|
const builder = new xml2js.Builder({ xmldec: { version: '1.0', encoding: 'UTF-8' } })
|
|
fs.writeFileSync(xmlFilePath, builder.buildObject(parsed))
|
|
console.log(`Enhanced RSS feed: ${allItems.length} items (${existingItems.length} posts + ${additionalItems.length} special)`)
|
|
}
|
|
|
|
exports.enhanceFeed = enhanceFeed
|