Skip to content

Commit

Permalink
feat(gatsby-plugin-feed): add match plugin option (#13827)
Browse files Browse the repository at this point in the history
  • Loading branch information
laysent authored and freiksenet committed May 21, 2019
1 parent 7aebf27 commit b827fd2
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 15 deletions.
2 changes: 2 additions & 0 deletions docs/docs/adding-an-rss-feed.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ This snippet contains a custom `gatsby-plugin-feed` setup in `gatsby-config.js`

The `output` field in your feed object allows you to customize the filename for your RSS feed, and `title` for the name of your site's RSS feed.

By default, feed is referenced in every page. You can customize this behavior by providing an extra field `match` of type `string`. This string will be used to build a `RegExp`, and this regular expression will be used to test the `pathname` of current page. Only pages that satisfied the regular expression will have feed reference included.

To see your feed in action, run `gatsby build && gatsby serve` and you can then inspect the content and URLs in your RSS file at `http://localhost:9000/rss.xml`.

> NOTE: if your blog has custom permalinks, such as links with or without dates in them, you may need to [customize `gatsby-node.js`](https://github.com/gatsbyjs/gatsby-starter-blog/blob/master/gatsby-node.js#L57) to output the correct URLs in your RSS feed. [Get in touch with us](/contributing/how-to-contribute/) if you need any help!
Expand Down
7 changes: 7 additions & 0 deletions packages/gatsby-plugin-feed/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ module.exports = {
`,
output: "/rss.xml",
title: "Your Site's RSS Feed",
// optional configuration to insert feed reference in pages:
// if `string` is used, it will be used to create RegExp and then test if pathname of
// current page satisfied this regular expression;
// if not provided or `undefined`, all pages will have feed reference inserted
match: "^/blog/",
},
],
},
Expand All @@ -71,6 +76,8 @@ module.exports = {

Each feed must include `output`, `query`, and `title`. Additionally, it is strongly recommended to pass a custom `serialize` function, otherwise an internal serialize function will be used which may not exactly match your particular use case.

`match` is an optional configuration, indicating which pages will have feed reference included. The accepted types of `match` are `string` or `undefined`. By default, when `match` is not configured, all pages will have feed reference inserted. If `string` is provided, it will be used to build a RegExp and then to test whether `pathname` of current page satisifed this regular expression. Only pages that satisifed this rule will have feed reference included.

All additional options are passed through to the [`rss`][rss] utillity. For more info on those additional options, [explore the `itemOptions` section of the `rss` package](https://www.npmjs.com/package/rss#itemoptions).

Check out an example of [how you could implement](https://www.gatsbyjs.org/docs/adding-an-rss-feed/) to your own site, with a custom `serialize` function, and additional functionality.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,29 @@ exports[`Adds <Link> for feed to head creates Link if feeds does exist 1`] = `
}
`;
exports[`Adds <Link> for feed to head creates Link only if pathname satisfied match 1`] = `
[MockFunction] {
"calls": Array [
Array [
Array [
<link
href="/gryffindor/feed.xml"
rel="alternate"
title="Gryffindor's RSS Feed"
type="application/rss+xml"
/>,
],
],
],
"results": Array [
Object {
"type": "return",
"value": undefined,
},
],
}
`;
exports[`Adds <Link> for feed to head creates Link with a title if it does exist 1`] = `
[MockFunction] {
"calls": Array [
Expand Down
29 changes: 29 additions & 0 deletions packages/gatsby-plugin-feed/src/__tests__/gatsby-ssr.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,33 @@ describe(`Adds <Link> for feed to head`, () => {
expect(setHeadComponents).toMatchSnapshot()
expect(setHeadComponents).toHaveBeenCalledTimes(1)
})

it(`creates Link only if pathname satisfied match`, async () => {
const pluginOptions = {
feeds: [
{
output: `gryffindor/feed.xml`,
title: `Gryffindor's RSS Feed`,
match: `^/gryffindor/`,
},
{
output: `ravenclaw/feed.xml`,
title: `Ravenclaw's RSS Feed`,
match: `^/ravenclaw/`,
},
],
}
const setHeadComponents = jest.fn()

await onRenderBody(
{
setHeadComponents,
pathname: `/gryffindor/welcome`,
},
pluginOptions
)

expect(setHeadComponents).toMatchSnapshot()
expect(setHeadComponents).toHaveBeenCalledTimes(1)
})
})
35 changes: 20 additions & 15 deletions packages/gatsby-plugin-feed/src/gatsby-ssr.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,32 @@ import { defaultOptions } from "./internals"
// TODO: remove for v3
const withPrefix = withAssetPrefix || fallbackWithPrefix

exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => {
exports.onRenderBody = ({ setHeadComponents, pathname }, pluginOptions) => {
const { feeds } = {
...defaultOptions,
...pluginOptions,
}

const links = feeds.map(({ output, title }, i) => {
if (output.charAt(0) !== `/`) {
output = `/` + output
}
const links = feeds
.filter(({ match }) => {
if (typeof match === `string`) return new RegExp(match).exec(pathname)
return true
})
.map(({ output, title }, i) => {
if (output.charAt(0) !== `/`) {
output = `/` + output
}

return (
<link
key={`gatsby-plugin-feed-${i}`}
rel="alternate"
type="application/rss+xml"
title={title}
href={withPrefix(output)}
/>
)
})
return (
<link
key={`gatsby-plugin-feed-${i}`}
rel="alternate"
type="application/rss+xml"
title={title}
href={withPrefix(output)}
/>
)
})

setHeadComponents(links)
}
1 change: 1 addition & 0 deletions packages/gatsby-plugin-feed/src/plugin-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const feed = Joi.object({
query: Joi.string().required(),
title: Joi.string(),
serialize: Joi.func(),
match: Joi.string(),
}).unknown(true)

// TODO: make feeds required in next major version bump
Expand Down

0 comments on commit b827fd2

Please sign in to comment.