first commit
This commit is contained in:
70
templates/blog-cloudflare/src/pages/rss.xml.ts
Normal file
70
templates/blog-cloudflare/src/pages/rss.xml.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import type { APIRoute } from "astro";
|
||||
import { getEmDashCollection } from "emdash";
|
||||
|
||||
const siteTitle = "My Blog";
|
||||
const siteDescription = "A blog about software, design, and the occasional stray thought.";
|
||||
|
||||
export const GET: APIRoute = async ({ site, url }) => {
|
||||
const siteUrl = site?.toString() || url.origin;
|
||||
|
||||
const { entries: posts } = await getEmDashCollection("posts", {
|
||||
orderBy: { published_at: "desc" },
|
||||
limit: 20,
|
||||
});
|
||||
|
||||
const items = posts
|
||||
.map((post) => {
|
||||
if (!post.data.publishedAt) return null;
|
||||
const pubDate = post.data.publishedAt.toUTCString();
|
||||
|
||||
const postUrl = `${siteUrl}/posts/${post.id}`;
|
||||
const title = escapeXml(post.data.title || "Untitled");
|
||||
const description = escapeXml(post.data.excerpt || "");
|
||||
|
||||
return ` <item>
|
||||
<title>${title}</title>
|
||||
<link>${postUrl}</link>
|
||||
<guid isPermaLink="true">${postUrl}</guid>
|
||||
<pubDate>${pubDate}</pubDate>
|
||||
<description>${description}</description>
|
||||
</item>`;
|
||||
})
|
||||
.filter(Boolean)
|
||||
.join("\n");
|
||||
|
||||
const rss = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>${escapeXml(siteTitle)}</title>
|
||||
<description>${escapeXml(siteDescription)}</description>
|
||||
<link>${siteUrl}</link>
|
||||
<atom:link href="${siteUrl}/rss.xml" rel="self" type="application/rss+xml"/>
|
||||
<language>en-us</language>
|
||||
<lastBuildDate>${new Date().toUTCString()}</lastBuildDate>
|
||||
${items}
|
||||
</channel>
|
||||
</rss>`;
|
||||
|
||||
return new Response(rss, {
|
||||
headers: {
|
||||
"Content-Type": "application/rss+xml; charset=utf-8",
|
||||
"Cache-Control": "public, max-age=3600",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const XML_ESCAPE_PATTERNS = [
|
||||
[/&/g, "&"],
|
||||
[/</g, "<"],
|
||||
[/>/g, ">"],
|
||||
[/"/g, """],
|
||||
[/'/g, "'"],
|
||||
] as const;
|
||||
|
||||
function escapeXml(str: string): string {
|
||||
let result = str;
|
||||
for (const [pattern, replacement] of XML_ESCAPE_PATTERNS) {
|
||||
result = result.replace(pattern, replacement);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user