Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(blog): allow processing blog posts through a processBlogPosts function #9886

Merged
merged 18 commits into from Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

@@ -1,5 +1,65 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`blog plugin process blog posts load content 1`] = `
[
{
"content": "2031",
"id": "/date/2031",
"metadata": {
"authors": [],
"date": 2031-01-01T00:00:00.000Z,
"description": "2031",
"editUrl": "https://baseEditUrl.com/edit/blog/date-2031-unlisted.md",
"formattedDate": "January 1, 2031",
OzakIOne marked this conversation as resolved.
Show resolved Hide resolved
"frontMatter": {
"date": 2031-01-01T00:00:00.000Z,
"slug": "/date/2031",
"title": "2031",
"unlisted": true,
},
"hasTruncateMarker": false,
"nextItem": {
"permalink": "/blog/date/2030",
"title": "2030",
},
"permalink": "/blog/date/2031",
"readingTime": 0.005,
"source": "@site/blog/date-2031-unlisted.md",
"tags": [],
"title": "2031",
"unlisted": false,
},
},
{
"content": "2030",
"id": "/date/2030",
"metadata": {
"authors": [],
"date": 2030-01-01T00:00:00.000Z,
"description": "2030",
"editUrl": "https://baseEditUrl.com/edit/blog/date-2030.md",
"formattedDate": "January 1, 2030",
"frontMatter": {
"date": 2030-01-01T00:00:00.000Z,
"slug": "/date/2030",
"title": "2030",
},
"hasTruncateMarker": false,
"permalink": "/blog/date/2030",
"prevItem": {
"permalink": "/blog/date/2031",
"title": "2031",
},
"readingTime": 0.005,
"source": "@site/blog/date-2030.md",
"tags": [],
"title": "2030",
"unlisted": false,
},
},
]
`;

exports[`blog plugin works on blog tags without pagination 1`] = `
{
"/blog/tags/tag-1": {
Expand Down
Expand Up @@ -14,10 +14,12 @@ import {
linkify,
getSourceToPermalink,
paginateBlogPosts,
applyProcessBlogPosts,
type LinkifyParams,
} from '../blogUtils';
import type {BlogBrokenMarkdownLink, BlogContentPaths} from '../types';
import type {BlogPost} from '@docusaurus/plugin-content-blog';
import type {DeepPartial} from 'utility-types';

describe('truncate', () => {
it('truncates texts', () => {
Expand Down Expand Up @@ -237,6 +239,7 @@ describe('linkify', () => {
frontMatter: {},
authors: [],
formattedDate: '',
unlisted: false,
},
content: '',
},
Expand Down Expand Up @@ -295,3 +298,99 @@ describe('linkify', () => {
} as BlogBrokenMarkdownLink);
});
});

const createBlogPost = (args: DeepPartial<BlogPost>): BlogPost => ({
id: '',
metadata: {
source: '',
title: '',
formattedDate: '',
permalink: '',
description: '',
hasTruncateMarker: false,
authors: [],
frontMatter: {},
tags: [],
unlisted: false,
...args.metadata,
} as BlogPost['metadata'],
content: args.content || '',
});

describe('processBlogPosts', () => {
const blogPost2022 = createBlogPost({
metadata: {date: new Date('2022-01-01')},
});
const blogPost2023 = createBlogPost({
metadata: {date: new Date('2023-01-01')},
});
const blogPost2024 = createBlogPost({
metadata: {date: new Date('2024-01-01')},
});

it('filter blogs only from 2024', async () => {
const processedBlogPosts = await applyProcessBlogPosts({
blogPosts: [blogPost2022, blogPost2023, blogPost2024],
processBlogPosts: async ({blogPosts}: {blogPosts: BlogPost[]}) =>
blogPosts.filter(
(blogPost) => blogPost.metadata.date.getFullYear() === 2024,
),
});

expect(processedBlogPosts).toEqual([blogPost2024]);
});

it('sort blogs by date in ascending order', async () => {
const processedBlogPosts = await applyProcessBlogPosts({
blogPosts: [blogPost2023, blogPost2022, blogPost2024],
processBlogPosts: async ({blogPosts}: {blogPosts: BlogPost[]}) =>
blogPosts.sort(
(a, b) => a.metadata.date.getTime() - b.metadata.date.getTime(),
),
});

expect(processedBlogPosts).toEqual([
blogPost2022,
blogPost2023,
blogPost2024,
]);
});

it('sort blogs by date in descending order', async () => {
const processedBlogPosts = await applyProcessBlogPosts({
blogPosts: [blogPost2023, blogPost2022, blogPost2024],
processBlogPosts: async ({blogPosts}: {blogPosts: BlogPost[]}) =>
blogPosts.sort(
(a, b) => b.metadata.date.getTime() - a.metadata.date.getTime(),
),
});

expect(processedBlogPosts).toEqual([
blogPost2024,
blogPost2023,
blogPost2022,
]);
});

it('processBlogPosts return 2022 only', async () => {
const processedBlogPosts = await applyProcessBlogPosts({
blogPosts: [blogPost2023, blogPost2022, blogPost2024],
processBlogPosts: async () => [blogPost2022],
});

expect(processedBlogPosts).toEqual([blogPost2022]);
});

it('processBlogPosts return undefined', async () => {
const processedBlogPosts = await applyProcessBlogPosts({
blogPosts: [blogPost2023, blogPost2022, blogPost2024],
processBlogPosts: async () => {},
});

expect(processedBlogPosts).toEqual([
blogPost2023,
blogPost2022,
blogPost2024,
]);
});
});
Expand Up @@ -511,7 +511,7 @@
sortPosts: 'ascending',
});
expect(normalOrder.reverse().map((x) => x.metadata.date)).toEqual(
reversedOrder.map((x) => x.metadata.date),

Check failure on line 514 in packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts

View workflow job for this annotation

GitHub Actions / Windows Tests (18.0)

blog plugin › process blog posts load content

expect(received).toMatchSnapshot() Snapshot name: `blog plugin process blog posts load content 1` - Snapshot - 2 + Received + 0 @@ -5,11 +5,10 @@ "metadata": { "authors": [], "date": 2031-01-01T00:00:00.000Z, "description": "2031", "editUrl": "https://baseEditUrl.com/edit/blog/date-2031-unlisted.md", - "formattedDate": "January 1, 2031", "frontMatter": { "date": 2031-01-01T00:00:00.000Z, "slug": "/date/2031", "title": "2031", "unlisted": true, @@ -33,11 +32,10 @@ "metadata": { "authors": [], "date": 2030-01-01T00:00:00.000Z, "description": "2030", "editUrl": "https://baseEditUrl.com/edit/blog/date-2030.md", - "formattedDate": "January 1, 2030", "frontMatter": { "date": 2030-01-01T00:00:00.000Z, "slug": "/date/2030", "title": "2030", }, at Object.toMatchSnapshot (packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts:514:32)

Check failure on line 514 in packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts

View workflow job for this annotation

GitHub Actions / Windows Tests (18)

blog plugin › process blog posts load content

expect(received).toMatchSnapshot() Snapshot name: `blog plugin process blog posts load content 1` - Snapshot - 2 + Received + 0 @@ -5,11 +5,10 @@ "metadata": { "authors": [], "date": 2031-01-01T00:00:00.000Z, "description": "2031", "editUrl": "https://baseEditUrl.com/edit/blog/date-2031-unlisted.md", - "formattedDate": "January 1, 2031", "frontMatter": { "date": 2031-01-01T00:00:00.000Z, "slug": "/date/2031", "title": "2031", "unlisted": true, @@ -33,11 +32,10 @@ "metadata": { "authors": [], "date": 2030-01-01T00:00:00.000Z, "description": "2030", "editUrl": "https://baseEditUrl.com/edit/blog/date-2030.md", - "formattedDate": "January 1, 2030", "frontMatter": { "date": 2030-01-01T00:00:00.000Z, "slug": "/date/2030", "title": "2030", }, at Object.toMatchSnapshot (packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts:514:32)

Check failure on line 514 in packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts

View workflow job for this annotation

GitHub Actions / Tests (18.0)

blog plugin › process blog posts load content

expect(received).toMatchSnapshot() Snapshot name: `blog plugin process blog posts load content 1` - Snapshot - 2 + Received + 0 @@ -5,11 +5,10 @@ "metadata": { "authors": [], "date": 2031-01-01T00:00:00.000Z, "description": "2031", "editUrl": "https://baseEditUrl.com/edit/blog/date-2031-unlisted.md", - "formattedDate": "January 1, 2031", "frontMatter": { "date": 2031-01-01T00:00:00.000Z, "slug": "/date/2031", "title": "2031", "unlisted": true, @@ -33,11 +32,10 @@ "metadata": { "authors": [], "date": 2030-01-01T00:00:00.000Z, "description": "2030", "editUrl": "https://baseEditUrl.com/edit/blog/date-2030.md", - "formattedDate": "January 1, 2030", "frontMatter": { "date": 2030-01-01T00:00:00.000Z, "slug": "/date/2030", "title": "2030", }, at Object.toMatchSnapshot (packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts:514:32)

Check failure on line 514 in packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts

View workflow job for this annotation

GitHub Actions / Tests (18)

blog plugin › process blog posts load content

expect(received).toMatchSnapshot() Snapshot name: `blog plugin process blog posts load content 1` - Snapshot - 2 + Received + 0 @@ -5,11 +5,10 @@ "metadata": { "authors": [], "date": 2031-01-01T00:00:00.000Z, "description": "2031", "editUrl": "https://baseEditUrl.com/edit/blog/date-2031-unlisted.md", - "formattedDate": "January 1, 2031", "frontMatter": { "date": 2031-01-01T00:00:00.000Z, "slug": "/date/2031", "title": "2031", "unlisted": true, @@ -33,11 +32,10 @@ "metadata": { "authors": [], "date": 2030-01-01T00:00:00.000Z, "description": "2030", "editUrl": "https://baseEditUrl.com/edit/blog/date-2030.md", - "formattedDate": "January 1, 2030", "frontMatter": { "date": 2030-01-01T00:00:00.000Z, "slug": "/date/2030", "title": "2030", }, at Object.toMatchSnapshot (packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts:514:32)

Check failure on line 514 in packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts

View workflow job for this annotation

GitHub Actions / Tests (20)

blog plugin › process blog posts load content

expect(received).toMatchSnapshot() Snapshot name: `blog plugin process blog posts load content 1` - Snapshot - 2 + Received + 0 @@ -5,11 +5,10 @@ "metadata": { "authors": [], "date": 2031-01-01T00:00:00.000Z, "description": "2031", "editUrl": "https://baseEditUrl.com/edit/blog/date-2031-unlisted.md", - "formattedDate": "January 1, 2031", "frontMatter": { "date": 2031-01-01T00:00:00.000Z, "slug": "/date/2031", "title": "2031", "unlisted": true, @@ -33,11 +32,10 @@ "metadata": { "authors": [], "date": 2030-01-01T00:00:00.000Z, "description": "2030", "editUrl": "https://baseEditUrl.com/edit/blog/date-2030.md", - "formattedDate": "January 1, 2030", "frontMatter": { "date": 2030-01-01T00:00:00.000Z, "slug": "/date/2030", "title": "2030", }, at Object.toMatchSnapshot (packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts:514:32)
);
});

Expand Down Expand Up @@ -541,4 +541,19 @@

expect(blogTags).toMatchSnapshot();
});

it('process blog posts load content', async () => {
const siteDir = path.join(
__dirname,
'__fixtures__',
'website-blog-with-dates',
);
OzakIOne marked this conversation as resolved.
Show resolved Hide resolved
const processedBlogPosts = await getBlogPosts(siteDir, {
postsPerPage: 2,
processBlogPosts: async ({blogPosts}) =>
blogPosts.filter((blog) => blog.metadata.date.getFullYear() > 2029),
});

expect(processedBlogPosts).toMatchSnapshot();
});
});
16 changes: 16 additions & 0 deletions packages/docusaurus-plugin-content-blog/src/blogUtils.ts
Expand Up @@ -446,3 +446,19 @@ export function linkify({

return newContent;
}

export async function applyProcessBlogPosts({
blogPosts,
processBlogPosts,
}: {
blogPosts: BlogPost[];
processBlogPosts: PluginOptions['processBlogPosts'];
}): Promise<BlogPost[]> {
const processedBlogPosts = await processBlogPosts({blogPosts});

if (Array.isArray(processedBlogPosts)) {
return processedBlogPosts;
}

return blogPosts;
}
9 changes: 7 additions & 2 deletions packages/docusaurus-plugin-content-blog/src/index.ts
Expand Up @@ -20,11 +20,12 @@ import {
DEFAULT_PLUGIN_ID,
} from '@docusaurus/utils';
import {
generateBlogPosts,
getSourceToPermalink,
getBlogTags,
paginateBlogPosts,
shouldBeListed,
applyProcessBlogPosts,
generateBlogPosts,
} from './blogUtils';
import footnoteIDFixer from './remark/footnoteIDFixer';
import {translateContent, getTranslationFiles} from './translations';
Expand Down Expand Up @@ -113,7 +114,11 @@ export default async function pluginContentBlog(

const baseBlogUrl = normalizeUrl([baseUrl, routeBasePath]);
const blogTagsListPath = normalizeUrl([baseBlogUrl, tagsBasePath]);
const blogPosts = await generateBlogPosts(contentPaths, context, options);
let blogPosts = await generateBlogPosts(contentPaths, context, options);
blogPosts = await applyProcessBlogPosts({
blogPosts,
processBlogPosts: options.processBlogPosts,
});
const listedBlogPosts = blogPosts.filter(shouldBeListed);

if (!blogPosts.length) {
Expand Down
4 changes: 4 additions & 0 deletions packages/docusaurus-plugin-content-blog/src/options.ts
Expand Up @@ -51,6 +51,7 @@ export const DEFAULT_OPTIONS: PluginOptions = {
authorsMapPath: 'authors.yml',
readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}),
sortPosts: 'descending',
processBlogPosts: async () => undefined,
};

const PluginOptionSchema = Joi.object<PluginOptions>({
Expand Down Expand Up @@ -134,6 +135,9 @@ const PluginOptionSchema = Joi.object<PluginOptions>({
sortPosts: Joi.string()
.valid('descending', 'ascending')
.default(DEFAULT_OPTIONS.sortPosts),
processBlogPosts: Joi.function()
.optional()
.default(() => DEFAULT_OPTIONS.processBlogPosts),
}).default(DEFAULT_OPTIONS);

export function validateOptions({
Expand Down
Expand Up @@ -335,6 +335,11 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
defaultReadingTime: ReadingTimeFunction;
},
) => number | undefined;

export type ProcessBlogPostsFn = (params: {
blogPosts: BlogPost[];
}) => Promise<void | BlogPost[]>;

/**
* Plugin options after normalization.
*/
Expand Down Expand Up @@ -426,6 +431,8 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
readingTime: ReadingTimeFunctionOption;
/** Governs the direction of blog post sorting. */
sortPosts: 'ascending' | 'descending';
/** TODO process blog posts. */
OzakIOne marked this conversation as resolved.
Show resolved Hide resolved
processBlogPosts: ProcessBlogPostsFn;
};

/**
Expand Down