-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add RSS feed #379
Add RSS feed #379
Changes from all commits
cd62048
eb45586
b69ce6f
b2aa3b8
b0d8068
cc2b16e
026e32a
dd7f406
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const SITE_TITLE = "MapLibre"; | ||
export const SITE_DESCRIPTION = | ||
"The MapLibre Organization is an umbrella for open-source mapping libraries."; | ||
Comment on lines
+1
to
+3
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I saw this on |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import type { APIContext } from "astro"; | ||
import rss, { type RSSFeedItem } from "@astrojs/rss"; | ||
import { | ||
getCollection, | ||
getEntry, | ||
render, | ||
type CollectionEntry, | ||
} from "astro:content"; | ||
import { experimental_AstroContainer as AstroContainer } from "astro/container"; | ||
import mdxRenderer from "@astrojs/mdx/server.js"; | ||
import solidRenderer from "@astrojs/solid-js/server.js"; | ||
|
||
import { transform, walk } from "ultrahtml"; | ||
import sanitize from "ultrahtml/transformers/sanitize"; | ||
|
||
import { SITE_TITLE, SITE_DESCRIPTION } from "../../constants"; | ||
|
||
// need to make this endpoint dynamic with only one path | ||
// otherwise the astro file will take precedence | ||
export function getStaticPaths() { | ||
return [{ params: { slug: "index" } }]; | ||
} | ||
|
||
const container = await AstroContainer.create({}); | ||
container.addServerRenderer({ renderer: mdxRenderer, name: "mdx" }); | ||
container.addServerRenderer({ renderer: solidRenderer, name: "solid" }); | ||
|
||
const getAuthors = async (authors: string[]): Promise<string> => { | ||
const authorEntries = await Promise.all( | ||
authors.map(async (author) => await getEntry("authors", author)), | ||
); | ||
|
||
const authorTitles = authorEntries | ||
.map((author) => author?.data?.title) | ||
.filter(Boolean); | ||
|
||
if (authorTitles.length > 1) { | ||
const lastAuthor = authorTitles.pop(); | ||
return `${authorTitles.join(", ")} and ${lastAuthor}`; | ||
} | ||
|
||
return authorTitles.join(", "); | ||
}; | ||
|
||
const getPost = async ( | ||
context: APIContext, | ||
post: CollectionEntry<"news">, | ||
): Promise<RSSFeedItem> => { | ||
const content = await transform( | ||
await container.renderToString((await render(post)).Content), | ||
[ | ||
async (node) => { | ||
await walk(node, async (node) => { | ||
if (node.name === "img" && node.attributes.src?.startsWith("/")) { | ||
node.attributes.src = context.site + node.attributes.src.slice(1); | ||
} | ||
}); | ||
return node; | ||
}, | ||
sanitize({ | ||
dropElements: ["script", "style"], | ||
}), | ||
], | ||
); | ||
|
||
return { | ||
title: post.data.title, | ||
pubDate: post.data.date, | ||
description: post.data.description, | ||
author: await getAuthors(post.data.authors), | ||
content, | ||
link: `/news/${post.id}/`, | ||
}; | ||
}; | ||
|
||
export async function GET(context: APIContext) { | ||
const news = await getCollection("news"); | ||
const items = news.sort((a, b) => +b.data.date - +a.data.date).slice(0, 15); | ||
|
||
return rss({ | ||
title: SITE_TITLE, | ||
description: SITE_DESCRIPTION, | ||
site: context.site || "", | ||
items: await Promise.all(items.map(async (post) => getPost(context, post))), | ||
customData: `<language>en-US</language><lastBuildDate>${new Date().toUTCString()}</lastBuildDate>`, | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
noting that this is also needed in a few places by the RSS feed, could look at another approach if you'd prefer.