CTAO Science Portal: static Astro site with git-based CMS (Sveltia + Gitea)
Portal code only; editorial content lives in the ctao/content repo on the demo machine's Gitea and is overlaid at build time (see README.md and deploy/README.md). Live demo: https://astro.isl-dev.grid.cyfronet.pl
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
// RSS 2.0 feed — hand-rolled static endpoint like search.json.js (no @astrojs/rss
|
||||
// dependency; the spec is 20 lines of XML). Newest 30 items, absolute URLs from
|
||||
// the configured `site`.
|
||||
import { getCollection } from 'astro:content';
|
||||
|
||||
const esc = (s = '') =>
|
||||
s.replace(/[<>&'"]/g, (c) => ({ '<': '<', '>': '>', '&': '&', "'": ''', '"': '"' })[c]);
|
||||
|
||||
export async function GET(context) {
|
||||
const site = context.site; // always set in astro.config.mjs
|
||||
const posts = (await getCollection('news', ({ data }) => !data.draft))
|
||||
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
|
||||
.slice(0, 30);
|
||||
|
||||
const items = posts
|
||||
.map((p) => {
|
||||
const url = new URL(`/news/${p.id}`, site).href;
|
||||
return ` <item>
|
||||
<title>${esc(p.data.title)}</title>
|
||||
<link>${url}</link>
|
||||
<guid isPermaLink="true">${url}</guid>
|
||||
<pubDate>${p.data.date.toUTCString()}</pubDate>
|
||||
<description>${esc(p.data.description)}</description>
|
||||
<category>${esc(p.data.category)}</category>
|
||||
</item>`;
|
||||
})
|
||||
.join('\n');
|
||||
|
||||
const xml = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>CTAO Science Portal News</title>
|
||||
<link>${new URL('/news', site).href}</link>
|
||||
<description>News and announcements of the Cherenkov Telescope Array Observatory</description>
|
||||
<language>en</language>
|
||||
<lastBuildDate>${(posts[0]?.data.date ?? new Date()).toUTCString()}</lastBuildDate>
|
||||
<atom:link href="${new URL('/rss.xml', site).href}" rel="self" type="application/rss+xml"/>
|
||||
${items}
|
||||
</channel>
|
||||
</rss>
|
||||
`;
|
||||
return new Response(xml, { headers: { 'Content-Type': 'application/rss+xml; charset=utf-8' } });
|
||||
}
|
||||
Reference in New Issue
Block a user