Skip to content

Commit

Permalink
feat(blog-plugin): limit option for blog feedOptions (#9189)
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnyreilly authored Aug 3, 2023
1 parent e0bb39a commit 4ecc86f
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 8 deletions.

Large diffs are not rendered by default.

43 changes: 43 additions & 0 deletions packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,4 +195,47 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => {
).toMatchSnapshot();
fsMock.mockClear();
});

it('filters to the first two entries using limit', async () => {
const siteDir = path.join(__dirname, '__fixtures__', 'website');
const outDir = path.join(siteDir, 'build-snap');
const siteConfig = {
title: 'Hello',
baseUrl: '/myBaseUrl/',
url: 'https://docusaurus.io',
favicon: 'image/favicon.ico',
};

// Build is quite difficult to mock, so we built the blog beforehand and
// copied the output to the fixture...
await testGenerateFeeds(
{
siteDir,
siteConfig,
i18n: DefaultI18N,
outDir,
} as LoadContext,
{
path: 'blog',
routeBasePath: 'blog',
tagsBasePath: 'tags',
authorsMapPath: 'authors.yml',
include: DEFAULT_OPTIONS.include,
exclude: DEFAULT_OPTIONS.exclude,
feedOptions: {
type: [feedType],
copyright: 'Copyright',
limit: 2,
},
readingTime: ({content, defaultReadingTime}) =>
defaultReadingTime({content}),
truncateMarker: /<!--\s*truncate\s*-->/,
} as PluginOptions,
);

expect(
fsMock.mock.calls.map((call) => call[1] as string),
).toMatchSnapshot();
fsMock.mockClear();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ describe('validateOptions', () => {
};
expect(testValidate(userOptions)).toEqual({
...userOptions,
feedOptions: {type: ['rss'], title: 'myTitle', copyright: ''},
feedOptions: {type: ['rss'], title: 'myTitle', copyright: '', limit: 20},
});
});

Expand All @@ -58,7 +58,6 @@ describe('validateOptions', () => {
beforeDefaultRehypePlugins: [markdownPluginsFunctionStub],
remarkPlugins: [[markdownPluginsFunctionStub, {option1: '42'}]],
rehypePlugins: [
// @ts-expect-error: it seems to work in practice
markdownPluginsObjectStub,
[markdownPluginsFunctionStub, {option1: '42'}],
],
Expand Down Expand Up @@ -95,7 +94,7 @@ describe('validateOptions', () => {
}),
).toEqual({
...defaultOptions,
feedOptions: {type: ['rss', 'atom', 'json'], copyright: ''},
feedOptions: {type: ['rss', 'atom', 'json'], copyright: '', limit: 20},
});
});

Expand All @@ -106,7 +105,7 @@ describe('validateOptions', () => {
}),
).toEqual({
...defaultOptions,
feedOptions: {type: null},
feedOptions: {type: null, limit: 20},
});
});

Expand All @@ -125,7 +124,12 @@ describe('validateOptions', () => {
}),
).toEqual({
...defaultOptions,
feedOptions: {type: ['rss', 'atom'], title: 'title', copyright: ''},
feedOptions: {
type: ['rss', 'atom'],
title: 'title',
copyright: '',
limit: 20,
},
});
});

Expand Down
9 changes: 7 additions & 2 deletions packages/docusaurus-plugin-content-blog/src/feed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ async function generateBlogFeed({
const {url: siteUrl, baseUrl, title, favicon} = siteConfig;
const blogBaseUrl = normalizeUrl([siteUrl, baseUrl, routeBasePath]);

const updated = blogPosts[0]?.metadata.date;
const blogPostsForFeed =
feedOptions.limit === false || feedOptions.limit === null
? blogPosts
: blogPosts.slice(0, feedOptions.limit);

const updated = blogPostsForFeed[0]?.metadata.date;

const feed = new Feed({
id: blogBaseUrl,
Expand All @@ -59,7 +64,7 @@ async function generateBlogFeed({
options.feedOptions.createFeedItems ?? defaultCreateFeedItems;

const feedItems = await createFeedItems({
blogPosts,
blogPosts: blogPostsForFeed,
siteConfig,
outDir,
defaultCreateFeedItems,
Expand Down
5 changes: 4 additions & 1 deletion packages/docusaurus-plugin-content-blog/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import type {
import type {OptionValidationContext} from '@docusaurus/types';

export const DEFAULT_OPTIONS: PluginOptions = {
feedOptions: {type: ['rss', 'atom'], copyright: ''},
feedOptions: {type: ['rss', 'atom'], copyright: '', limit: 20},
beforeDefaultRehypePlugins: [],
beforeDefaultRemarkPlugins: [],
admonitions: true,
Expand Down Expand Up @@ -123,6 +123,9 @@ const PluginOptionSchema = Joi.object<PluginOptions>({
}),
language: Joi.string(),
createFeedItems: Joi.function(),
limit: Joi.alternatives()
.try(Joi.number(), Joi.valid(null), Joi.valid(false))
.default(DEFAULT_OPTIONS.feedOptions.limit),
}).default(DEFAULT_OPTIONS.feedOptions),
authorsMapPath: Joi.string().default(DEFAULT_OPTIONS.authorsMapPath),
readingTime: Joi.function().default(() => DEFAULT_OPTIONS.readingTime),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
language?: string;
/** Allow control over the construction of BlogFeedItems */
createFeedItems?: CreateFeedItemsFn;
/** Limits the feed to the specified number of posts, false|null for all */
limit?: number | false | null;
};

type DefaultCreateFeedItemsParams = {
Expand Down
1 change: 1 addition & 0 deletions website/docs/api/plugins/plugin-content-blog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Accepted fields:
| `feedOptions` | _See below_ | `{type: ['rss', 'atom']}` | Blog feed. |
| `feedOptions.type` | <code><a href="#FeedType">FeedType</a> \| <a href="#FeedType">FeedType</a>[] \| 'all' \| null</code> | **Required** | Type of feed to be generated. Use `null` to disable generation. |
| `feedOptions.createFeedItems` | <code><a href="#CreateFeedItemsFn">CreateFeedItemsFn</a> \| undefined</code> | `undefined` | An optional function which can be used to transform and / or filter the items in the feed. |
| `feedOptions.limit` | `number \| null \| false` | `20` | Limits the feed to the specified number of posts, `false` or `null` for all entries. Defaults to `20`. |
| `feedOptions.title` | `string` | `siteConfig.title` | Title of the feed. |
| `feedOptions.description` | `string` | <code>\`$\{siteConfig.title} Blog\`</code> | Description of the feed. |
| `feedOptions.copyright` | `string` | `undefined` | Copyright message. |
Expand Down
1 change: 1 addition & 0 deletions website/docs/blog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ type BlogOptions = {
description?: string;
copyright: string;
language?: string; // possible values: http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
limit?: number | false | null; // defaults to 20
/** Allow control over the construction of BlogFeedItems */
createFeedItems?: (params: {
blogPosts: BlogPost[];
Expand Down

0 comments on commit 4ecc86f

Please sign in to comment.