From 85ad1aab67b9f1b9214db3200458ac37675b9afb Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Wed, 19 Jan 2022 14:34:52 -0600 Subject: [PATCH] feat: add support for styled RSS feeds (#2371) --- .changeset/five-crabs-sparkle.md | 5 + docs/src/pages/en/guides/rss.md | 12 ++- packages/astro/src/@types/astro.ts | 9 +- packages/astro/src/core/build/page-data.ts | 19 +++- packages/astro/src/core/ssr/rss.ts | 33 +++++-- packages/astro/src/core/util.ts | 104 +++++++++++++++++++++ 6 files changed, 170 insertions(+), 12 deletions(-) create mode 100644 .changeset/five-crabs-sparkle.md diff --git a/.changeset/five-crabs-sparkle.md b/.changeset/five-crabs-sparkle.md new file mode 100644 index 000000000..00b79c699 --- /dev/null +++ b/.changeset/five-crabs-sparkle.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Add support for styled RSS feeds using the new `stylesheet` option diff --git a/docs/src/pages/en/guides/rss.md b/docs/src/pages/en/guides/rss.md index 67e135604..b40fa98de 100644 --- a/docs/src/pages/en/guides/rss.md +++ b/docs/src/pages/en/guides/rss.md @@ -4,7 +4,7 @@ title: RSS description: An intro to RSS in Astro --- -Astro supports fast, automatic RSS feed generation for blogs and other content websites. +Astro supports fast, automatic RSS feed generation for blogs and other content websites. For more information about RSS feeds in general, see [aboutfeeds.com](https://aboutfeeds.com/). You can create an RSS feed from any Astro page that uses a `getStaticPaths()` function for routing. Only dynamic routes can use `getStaticPaths()` today (see [Routing](/en/core-concepts/routing)). @@ -22,6 +22,8 @@ export async function getStaticPaths({rss}) { rss({ // The RSS Feed title, description, and custom metadata. title: 'Don\'s Blog', + // See "Styling" section below + stylesheet: true, description: 'An example blog on Astro', customData: `en-us`, // The list of items for your RSS feed, sorted. @@ -41,3 +43,11 @@ export async function getStaticPaths({rss}) { ``` Note: RSS feeds will **not** be built during development. Currently, RSS feeds are only generated during your final build. + +### Styling + +RSS Feeds can be styled with an XSL stylesheet for a more pleasant user experience when they are opened directly in a browser. By default, Astro does not set a stylesheet for RSS feeds, but it can be enabled by setting the `stylesheet` option. + +Astro can automatically use [Pretty Feed](https://github.com/genmon/aboutfeeds/blob/main/tools/pretty-feed-v3.xsl), a popular open-source XSL stylesheet. To enable this behavior, pass `stylesheet: true`. + +If you'd like to use a custom XSL stylesheet, you can pass a string value like `stylesheet: '/my-custom-stylesheet.xsl'`. This file should be in your `public/` directory (in this case, `public/my-custom-stylesheet.xsl`). diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index a96bb10e9..3df6bf41c 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -339,6 +339,12 @@ export interface RSS { description: string; /** Specify arbitrary metadata on opening tag */ xmlns?: Record; + /** + * If false (default), does not include XSL stylesheet. + * If true, automatically includes 'pretty-feed-v3'. + * If a string value, specifies a local custom XSL stylesheet, for example '/custom-feed.xsl'. + */ + stylesheet?: string | boolean; /** Specify custom data in opening of file */ customData?: string; /** @@ -364,7 +370,8 @@ export interface RSS { export type RSSFunction = (args: RSS) => void; -export type RSSResult = { url: string; xml?: string }; +export type FeedResult = { url: string; content?: string; }; +export type RSSResult = { xml: FeedResult; xsl?: FeedResult }; export type SSRError = Error & vite.ErrorPayload['err']; diff --git a/packages/astro/src/core/build/page-data.ts b/packages/astro/src/core/build/page-data.ts index f2d3472e5..45b7a6089 100644 --- a/packages/astro/src/core/build/page-data.ts +++ b/packages/astro/src/core/build/page-data.ts @@ -79,11 +79,22 @@ export async function collectPagesData(opts: CollectPagesDataOptions): Promise`; + if (typeof rssData.stylesheet === 'string') { + xml += ``; + } + xml += ` + + + + + + + <xsl:value-of select="/rss/channel/title"/> Web Feed + + + + + + +
+
+

+ + + + + + + + + + + + + + + + + + + Web Feed Preview +

+

+

+ + + + + Visit Website → + +
+

Recent Items

+ +
+

+ + + + + + +

+ + Published: + +
+
+
+ + +
+
`;