Skip to content

Commit 081e0a9

Browse files
authored
feat(astro-rss): generate post content in feed (#5366)
1 parent a72a131 commit 081e0a9

4 files changed

Lines changed: 46 additions & 1 deletion

File tree

.changeset/purple-knives-tan.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@astrojs/rss': minor
3+
---
4+
5+
Added the ability for users to include the full content of their posts/items in each RSS feed entry
6+
via the new `content` key on the `RSSFeedItem` model.

packages/astro-rss/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ type RSSFeedItem = {
9595
pubDate: Date;
9696
/** Item description */
9797
description?: string;
98+
/** Full content of the item, should be valid HTML */
99+
content?: string;
98100
/** Append some other XML-valid data to this item */
99101
customData?: string;
100102
};

packages/astro-rss/src/index.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ type RSSFeedItem = {
3939
pubDate: Date;
4040
/** Item description */
4141
description?: string;
42+
/** Full content of the item, should be valid HTML */
43+
content?: string;
4244
/** Append some other XML-valid data to this item */
4345
customData?: string;
4446
};
@@ -103,6 +105,15 @@ export async function generateRSS({ rssOptions, items }: GenerateRSSArgs): Promi
103105
xml += `<?xml-stylesheet href="${rssOptions.stylesheet}" type="text/xsl"?>`;
104106
}
105107
xml += `<rss version="2.0"`;
108+
if (items.find((result) => result.content)) {
109+
// the namespace to be added to the xmlns:content attribute to enable the <content> RSS feature
110+
const XMLContentNamespace = 'http://purl.org/rss/1.0/modules/content/';
111+
xml += ` xmlns:content="${XMLContentNamespace}"`;
112+
// Ensure that the user hasn't tried to manually include the necessary namespace themselves
113+
if (rssOptions.xmlns?.content && rssOptions.xmlns.content === XMLContentNamespace) {
114+
delete rssOptions.xmlns.content;
115+
}
116+
}
106117

107118
// xmlns
108119
if (rssOptions.xmlns) {
@@ -139,6 +150,10 @@ export async function generateRSS({ rssOptions, items }: GenerateRSSArgs): Promi
139150
}
140151
xml += `<pubDate>${result.pubDate.toUTCString()}</pubDate>`;
141152
}
153+
// include the full content of the post if the user supplies it
154+
if (typeof result.content === 'string') {
155+
xml += `<content:encoded><![CDATA[${result.content}]]></content:encoded>`;
156+
}
142157
if (typeof result.customData === 'string') xml += result.customData;
143158
xml += `</item>`;
144159
}

packages/astro-rss/test/rss.test.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ const phpFeedItem = {
1515
description:
1616
'PHP is a general-purpose scripting language geared toward web development. It was originally created by Danish-Canadian programmer Rasmus Lerdorf in 1994.',
1717
};
18+
const phpFeedItemWithContent = {
19+
...phpFeedItem,
20+
content: `<h1>${phpFeedItem.title}</h1><p>${phpFeedItem.description}</p>`,
21+
};
1822

1923
const web1FeedItem = {
2024
// Should support empty string as a URL (possible for homepage route)
@@ -24,10 +28,17 @@ const web1FeedItem = {
2428
description:
2529
'Web 1.0 is the term used for the earliest version of the Internet as it emerged from its origins with Defense Advanced Research Projects Agency (DARPA) and became, for the first time, a global network representing the future of digital communications.',
2630
};
31+
const web1FeedItemWithContent = {
32+
...web1FeedItem,
33+
content: `<h1>${web1FeedItem.title}</h1><p>${web1FeedItem.description}</p>`,
34+
};
2735

2836
// note: I spent 30 minutes looking for a nice node-based snapshot tool
2937
// ...and I gave up. Enjoy big strings!
30-
const validXmlResult = `<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title><![CDATA[My RSS feed]]></title><description><![CDATA[This sure is a nice RSS feed]]></description><link>https://example.com/</link><item><title><![CDATA[Remember PHP?]]></title><link>https://example.com/php/</link><guid>https://example.com/php/</guid><description><![CDATA[PHP is a general-purpose scripting language geared toward web development. It was originally created by Danish-Canadian programmer Rasmus Lerdorf in 1994.]]></description><pubDate>Tue, 03 May 1994 00:00:00 GMT</pubDate></item><item><title><![CDATA[Web 1.0]]></title><link>https://example.com/</link><guid>https://example.com/</guid><description><![CDATA[Web 1.0 is the term used for the earliest version of the Internet as it emerged from its origins with Defense Advanced Research Projects Agency (DARPA) and became, for the first time, a global network representing the future of digital communications.]]></description><pubDate>Sat, 03 May 1997 00:00:00 GMT</pubDate></item></channel></rss>`;
38+
// prettier-ignore
39+
const validXmlResult = `<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title><![CDATA[${title}]]></title><description><![CDATA[${description}]]></description><link>${site}/</link><item><title><![CDATA[${phpFeedItem.title}]]></title><link>${site}${phpFeedItem.link}/</link><guid>${site}${phpFeedItem.link}/</guid><description><![CDATA[${phpFeedItem.description}]]></description><pubDate>${new Date(phpFeedItem.pubDate).toUTCString()}</pubDate></item><item><title><![CDATA[${web1FeedItem.title}]]></title><link>${site}${web1FeedItem.link}/</link><guid>${site}${web1FeedItem.link}/</guid><description><![CDATA[${web1FeedItem.description}]]></description><pubDate>${new Date(web1FeedItem.pubDate).toUTCString()}</pubDate></item></channel></rss>`;
40+
// prettier-ignore
41+
const validXmlWithContentResult = `<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title><![CDATA[${title}]]></title><description><![CDATA[${description}]]></description><link>${site}/</link><item><title><![CDATA[${phpFeedItemWithContent.title}]]></title><link>${site}${phpFeedItemWithContent.link}/</link><guid>${site}${phpFeedItemWithContent.link}/</guid><description><![CDATA[${phpFeedItemWithContent.description}]]></description><pubDate>${new Date(phpFeedItemWithContent.pubDate).toUTCString()}</pubDate><content:encoded><![CDATA[${phpFeedItemWithContent.content}]]></content:encoded></item><item><title><![CDATA[${web1FeedItemWithContent.title}]]></title><link>${site}${web1FeedItemWithContent.link}/</link><guid>${site}${web1FeedItemWithContent.link}/</guid><description><![CDATA[${web1FeedItemWithContent.description}]]></description><pubDate>${new Date(web1FeedItemWithContent.pubDate).toUTCString()}</pubDate><content:encoded><![CDATA[${web1FeedItemWithContent.content}]]></content:encoded></item></channel></rss>`;
3142

3243
describe('rss', () => {
3344
it('should generate on valid RSSFeedItem array', async () => {
@@ -41,6 +52,17 @@ describe('rss', () => {
4152
chai.expect(body).to.equal(validXmlResult);
4253
});
4354

55+
it('should generate on valid RSSFeedItem array with HTML content included', async () => {
56+
const { body } = await rss({
57+
title,
58+
description,
59+
items: [phpFeedItemWithContent, web1FeedItemWithContent],
60+
site,
61+
});
62+
63+
chai.expect(body).to.equal(validXmlWithContentResult);
64+
});
65+
4466
describe('glob result', () => {
4567
it('should generate on valid result', async () => {
4668
const globResult = {

0 commit comments

Comments
 (0)