mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-07 22:27:11 +02:00
feat(blog): allow processing blog posts through a processBlogPosts function (#9886)
Co-authored-by: OzakIOne <OzakIOne@users.noreply.github.com> Co-authored-by: sebastien <lorber.sebastien@gmail.com> Co-authored-by: Sébastien Lorber <slorber@users.noreply.github.com>
This commit is contained in:
parent
05279dc3d8
commit
2851c93d0d
12 changed files with 400 additions and 6 deletions
|
@ -55,5 +55,8 @@
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0"
|
"node": ">=18.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@total-typescript/shoehorn": "^0.1.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,244 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`blog plugin process blog posts load content 1`] = `
|
||||||
|
{
|
||||||
|
"/blog/tags/tag-1": {
|
||||||
|
"items": [
|
||||||
|
"/simple/slug/another",
|
||||||
|
"/another/tags",
|
||||||
|
"/another/tags2",
|
||||||
|
],
|
||||||
|
"label": "tag1",
|
||||||
|
"pages": [
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
"/simple/slug/another",
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"blogDescription": "Blog",
|
||||||
|
"blogTitle": "Blog",
|
||||||
|
"nextPage": "/blog/tags/tag-1/page/2",
|
||||||
|
"page": 1,
|
||||||
|
"permalink": "/blog/tags/tag-1",
|
||||||
|
"postsPerPage": 1,
|
||||||
|
"previousPage": undefined,
|
||||||
|
"totalCount": 3,
|
||||||
|
"totalPages": 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
"/another/tags",
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"blogDescription": "Blog",
|
||||||
|
"blogTitle": "Blog",
|
||||||
|
"nextPage": "/blog/tags/tag-1/page/3",
|
||||||
|
"page": 2,
|
||||||
|
"permalink": "/blog/tags/tag-1/page/2",
|
||||||
|
"postsPerPage": 1,
|
||||||
|
"previousPage": "/blog/tags/tag-1",
|
||||||
|
"totalCount": 3,
|
||||||
|
"totalPages": 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
"/another/tags2",
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"blogDescription": "Blog",
|
||||||
|
"blogTitle": "Blog",
|
||||||
|
"nextPage": undefined,
|
||||||
|
"page": 3,
|
||||||
|
"permalink": "/blog/tags/tag-1/page/3",
|
||||||
|
"postsPerPage": 1,
|
||||||
|
"previousPage": "/blog/tags/tag-1/page/2",
|
||||||
|
"totalCount": 3,
|
||||||
|
"totalPages": 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"permalink": "/blog/tags/tag-1",
|
||||||
|
"unlisted": false,
|
||||||
|
},
|
||||||
|
"/blog/tags/tag-2": {
|
||||||
|
"items": [
|
||||||
|
"/another/tags",
|
||||||
|
"/another/tags2",
|
||||||
|
],
|
||||||
|
"label": "tag2",
|
||||||
|
"pages": [
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
"/another/tags",
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"blogDescription": "Blog",
|
||||||
|
"blogTitle": "Blog",
|
||||||
|
"nextPage": "/blog/tags/tag-2/page/2",
|
||||||
|
"page": 1,
|
||||||
|
"permalink": "/blog/tags/tag-2",
|
||||||
|
"postsPerPage": 1,
|
||||||
|
"previousPage": undefined,
|
||||||
|
"totalCount": 2,
|
||||||
|
"totalPages": 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
"/another/tags2",
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"blogDescription": "Blog",
|
||||||
|
"blogTitle": "Blog",
|
||||||
|
"nextPage": undefined,
|
||||||
|
"page": 2,
|
||||||
|
"permalink": "/blog/tags/tag-2/page/2",
|
||||||
|
"postsPerPage": 1,
|
||||||
|
"previousPage": "/blog/tags/tag-2",
|
||||||
|
"totalCount": 2,
|
||||||
|
"totalPages": 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"permalink": "/blog/tags/tag-2",
|
||||||
|
"unlisted": false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`blog plugin process blog posts load content 2`] = `
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"content": "simple url slug",
|
||||||
|
"id": "/simple/slug/another",
|
||||||
|
"metadata": {
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"imageURL": undefined,
|
||||||
|
"name": "Sébastien Lorber",
|
||||||
|
"title": "Docusaurus maintainer",
|
||||||
|
"url": "https://sebastienlorber.com",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"date": 2020-08-15T00:00:00.000Z,
|
||||||
|
"description": "simple url slug",
|
||||||
|
"editUrl": "https://baseEditUrl.com/edit/blog/another-simple-slug-with-tags.md",
|
||||||
|
"frontMatter": {
|
||||||
|
"author": "Sébastien Lorber",
|
||||||
|
"author_title": "Docusaurus maintainer",
|
||||||
|
"author_url": "https://sebastienlorber.com",
|
||||||
|
"date": 2020-08-15T00:00:00.000Z,
|
||||||
|
"slug": "/simple/slug/another",
|
||||||
|
"tags": [
|
||||||
|
"tag1",
|
||||||
|
],
|
||||||
|
"title": "Another Simple Slug",
|
||||||
|
},
|
||||||
|
"hasTruncateMarker": false,
|
||||||
|
"nextItem": {
|
||||||
|
"permalink": "/blog/another/tags",
|
||||||
|
"title": "Another With Tag",
|
||||||
|
},
|
||||||
|
"permalink": "/blog/simple/slug/another",
|
||||||
|
"readingTime": 0.015,
|
||||||
|
"source": "@site/blog/another-simple-slug-with-tags.md",
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"label": "tag1",
|
||||||
|
"permalink": "/blog/tags/tag-1",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"title": "Another Simple Slug",
|
||||||
|
"unlisted": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "with tag",
|
||||||
|
"id": "/another/tags",
|
||||||
|
"metadata": {
|
||||||
|
"authors": [],
|
||||||
|
"date": 2020-08-15T00:00:00.000Z,
|
||||||
|
"description": "with tag",
|
||||||
|
"editUrl": "https://baseEditUrl.com/edit/blog/another-with-tags.md",
|
||||||
|
"frontMatter": {
|
||||||
|
"date": 2020-08-15T00:00:00.000Z,
|
||||||
|
"slug": "/another/tags",
|
||||||
|
"tags": [
|
||||||
|
"tag1",
|
||||||
|
"tag2",
|
||||||
|
],
|
||||||
|
"title": "Another With Tag",
|
||||||
|
},
|
||||||
|
"hasTruncateMarker": false,
|
||||||
|
"nextItem": {
|
||||||
|
"permalink": "/blog/another/tags2",
|
||||||
|
"title": "Another With Tag",
|
||||||
|
},
|
||||||
|
"permalink": "/blog/another/tags",
|
||||||
|
"prevItem": {
|
||||||
|
"permalink": "/blog/simple/slug/another",
|
||||||
|
"title": "Another Simple Slug",
|
||||||
|
},
|
||||||
|
"readingTime": 0.01,
|
||||||
|
"source": "@site/blog/another-with-tags.md",
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"label": "tag1",
|
||||||
|
"permalink": "/blog/tags/tag-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "tag2",
|
||||||
|
"permalink": "/blog/tags/tag-2",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"title": "Another With Tag",
|
||||||
|
"unlisted": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "with tag",
|
||||||
|
"id": "/another/tags2",
|
||||||
|
"metadata": {
|
||||||
|
"authors": [],
|
||||||
|
"date": 2020-08-15T00:00:00.000Z,
|
||||||
|
"description": "with tag",
|
||||||
|
"editUrl": "https://baseEditUrl.com/edit/blog/another-with-tags2.md",
|
||||||
|
"frontMatter": {
|
||||||
|
"date": 2020-08-15T00:00:00.000Z,
|
||||||
|
"slug": "/another/tags2",
|
||||||
|
"tags": [
|
||||||
|
"tag1",
|
||||||
|
"tag2",
|
||||||
|
],
|
||||||
|
"title": "Another With Tag",
|
||||||
|
},
|
||||||
|
"hasTruncateMarker": false,
|
||||||
|
"permalink": "/blog/another/tags2",
|
||||||
|
"prevItem": {
|
||||||
|
"permalink": "/blog/another/tags",
|
||||||
|
"title": "Another With Tag",
|
||||||
|
},
|
||||||
|
"readingTime": 0.01,
|
||||||
|
"source": "@site/blog/another-with-tags2.md",
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"label": "tag1",
|
||||||
|
"permalink": "/blog/tags/tag-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "tag2",
|
||||||
|
"permalink": "/blog/tags/tag-2",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"title": "Another With Tag",
|
||||||
|
"unlisted": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`blog plugin works on blog tags without pagination 1`] = `
|
exports[`blog plugin works on blog tags without pagination 1`] = `
|
||||||
{
|
{
|
||||||
"/blog/tags/tag-1": {
|
"/blog/tags/tag-1": {
|
||||||
|
|
|
@ -50,7 +50,6 @@ exports[`translateContent falls back when translation is incomplete 1`] = `
|
||||||
"authors": [],
|
"authors": [],
|
||||||
"date": 2021-07-19T00:00:00.000Z,
|
"date": 2021-07-19T00:00:00.000Z,
|
||||||
"description": "/blog/2021/06/19/hello",
|
"description": "/blog/2021/06/19/hello",
|
||||||
"formattedDate": "June 19, 2021",
|
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"hasTruncateMarker": true,
|
"hasTruncateMarker": true,
|
||||||
"permalink": "/blog/2021/06/19/hello",
|
"permalink": "/blog/2021/06/19/hello",
|
||||||
|
@ -94,7 +93,6 @@ exports[`translateContent returns translated loaded 1`] = `
|
||||||
"authors": [],
|
"authors": [],
|
||||||
"date": 2021-07-19T00:00:00.000Z,
|
"date": 2021-07-19T00:00:00.000Z,
|
||||||
"description": "/blog/2021/06/19/hello",
|
"description": "/blog/2021/06/19/hello",
|
||||||
"formattedDate": "June 19, 2021",
|
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"hasTruncateMarker": true,
|
"hasTruncateMarker": true,
|
||||||
"permalink": "/blog/2021/06/19/hello",
|
"permalink": "/blog/2021/06/19/hello",
|
||||||
|
|
|
@ -8,12 +8,14 @@
|
||||||
import {jest} from '@jest/globals';
|
import {jest} from '@jest/globals';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
import {fromPartial} from '@total-typescript/shoehorn';
|
||||||
import {
|
import {
|
||||||
truncate,
|
truncate,
|
||||||
parseBlogFileName,
|
parseBlogFileName,
|
||||||
linkify,
|
linkify,
|
||||||
getSourceToPermalink,
|
getSourceToPermalink,
|
||||||
paginateBlogPosts,
|
paginateBlogPosts,
|
||||||
|
applyProcessBlogPosts,
|
||||||
type LinkifyParams,
|
type LinkifyParams,
|
||||||
} from '../blogUtils';
|
} from '../blogUtils';
|
||||||
import type {BlogBrokenMarkdownLink, BlogContentPaths} from '../types';
|
import type {BlogBrokenMarkdownLink, BlogContentPaths} from '../types';
|
||||||
|
@ -236,7 +238,7 @@ describe('linkify', () => {
|
||||||
hasTruncateMarker: false,
|
hasTruncateMarker: false,
|
||||||
frontMatter: {},
|
frontMatter: {},
|
||||||
authors: [],
|
authors: [],
|
||||||
formattedDate: '',
|
unlisted: false,
|
||||||
},
|
},
|
||||||
content: '',
|
content: '',
|
||||||
},
|
},
|
||||||
|
@ -295,3 +297,81 @@ describe('linkify', () => {
|
||||||
} as BlogBrokenMarkdownLink);
|
} as BlogBrokenMarkdownLink);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('processBlogPosts', () => {
|
||||||
|
const blogPost2022: BlogPost = fromPartial({
|
||||||
|
metadata: {date: new Date('2022-01-01')},
|
||||||
|
});
|
||||||
|
const blogPost2023: BlogPost = fromPartial({
|
||||||
|
metadata: {date: new Date('2023-01-01')},
|
||||||
|
});
|
||||||
|
const blogPost2024: BlogPost = fromPartial({
|
||||||
|
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,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -498,4 +498,31 @@ describe('blog plugin', () => {
|
||||||
|
|
||||||
expect(blogTags).toMatchSnapshot();
|
expect(blogTags).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('process blog posts load content', async () => {
|
||||||
|
const siteDir = path.join(
|
||||||
|
__dirname,
|
||||||
|
'__fixtures__',
|
||||||
|
'website-blog-with-tags',
|
||||||
|
);
|
||||||
|
const plugin = await getPlugin(
|
||||||
|
siteDir,
|
||||||
|
{
|
||||||
|
postsPerPage: 1,
|
||||||
|
processBlogPosts: async ({blogPosts}) =>
|
||||||
|
blogPosts.filter((blog) => blog.metadata.tags[0].label === 'tag1'),
|
||||||
|
},
|
||||||
|
DefaultI18N,
|
||||||
|
);
|
||||||
|
const {blogPosts, blogTags, blogListPaginated} =
|
||||||
|
(await plugin.loadContent!())!;
|
||||||
|
|
||||||
|
expect(blogListPaginated).toHaveLength(3);
|
||||||
|
|
||||||
|
expect(Object.keys(blogTags)).toHaveLength(2);
|
||||||
|
expect(blogTags).toMatchSnapshot();
|
||||||
|
|
||||||
|
expect(blogPosts).toHaveLength(3);
|
||||||
|
expect(blogPosts).toMatchSnapshot();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -29,7 +29,6 @@ const sampleBlogPosts: BlogPost[] = [
|
||||||
source: '/blog/2021/06/19/hello',
|
source: '/blog/2021/06/19/hello',
|
||||||
description: '/blog/2021/06/19/hello',
|
description: '/blog/2021/06/19/hello',
|
||||||
date: new Date(2021, 6, 19),
|
date: new Date(2021, 6, 19),
|
||||||
formattedDate: 'June 19, 2021',
|
|
||||||
tags: [],
|
tags: [],
|
||||||
title: 'Hello',
|
title: 'Hello',
|
||||||
hasTruncateMarker: true,
|
hasTruncateMarker: true,
|
||||||
|
|
|
@ -422,3 +422,19 @@ export function linkify({
|
||||||
|
|
||||||
return newContent;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -20,11 +20,12 @@ import {
|
||||||
DEFAULT_PLUGIN_ID,
|
DEFAULT_PLUGIN_ID,
|
||||||
} from '@docusaurus/utils';
|
} from '@docusaurus/utils';
|
||||||
import {
|
import {
|
||||||
generateBlogPosts,
|
|
||||||
getSourceToPermalink,
|
getSourceToPermalink,
|
||||||
getBlogTags,
|
getBlogTags,
|
||||||
paginateBlogPosts,
|
paginateBlogPosts,
|
||||||
shouldBeListed,
|
shouldBeListed,
|
||||||
|
applyProcessBlogPosts,
|
||||||
|
generateBlogPosts,
|
||||||
} from './blogUtils';
|
} from './blogUtils';
|
||||||
import footnoteIDFixer from './remark/footnoteIDFixer';
|
import footnoteIDFixer from './remark/footnoteIDFixer';
|
||||||
import {translateContent, getTranslationFiles} from './translations';
|
import {translateContent, getTranslationFiles} from './translations';
|
||||||
|
@ -113,7 +114,11 @@ export default async function pluginContentBlog(
|
||||||
|
|
||||||
const baseBlogUrl = normalizeUrl([baseUrl, routeBasePath]);
|
const baseBlogUrl = normalizeUrl([baseUrl, routeBasePath]);
|
||||||
const blogTagsListPath = normalizeUrl([baseBlogUrl, tagsBasePath]);
|
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);
|
const listedBlogPosts = blogPosts.filter(shouldBeListed);
|
||||||
|
|
||||||
if (!blogPosts.length) {
|
if (!blogPosts.length) {
|
||||||
|
|
|
@ -51,6 +51,7 @@ export const DEFAULT_OPTIONS: PluginOptions = {
|
||||||
authorsMapPath: 'authors.yml',
|
authorsMapPath: 'authors.yml',
|
||||||
readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}),
|
readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}),
|
||||||
sortPosts: 'descending',
|
sortPosts: 'descending',
|
||||||
|
processBlogPosts: async () => undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
const PluginOptionSchema = Joi.object<PluginOptions>({
|
const PluginOptionSchema = Joi.object<PluginOptions>({
|
||||||
|
@ -134,6 +135,9 @@ const PluginOptionSchema = Joi.object<PluginOptions>({
|
||||||
sortPosts: Joi.string()
|
sortPosts: Joi.string()
|
||||||
.valid('descending', 'ascending')
|
.valid('descending', 'ascending')
|
||||||
.default(DEFAULT_OPTIONS.sortPosts),
|
.default(DEFAULT_OPTIONS.sortPosts),
|
||||||
|
processBlogPosts: Joi.function()
|
||||||
|
.optional()
|
||||||
|
.default(() => DEFAULT_OPTIONS.processBlogPosts),
|
||||||
}).default(DEFAULT_OPTIONS);
|
}).default(DEFAULT_OPTIONS);
|
||||||
|
|
||||||
export function validateOptions({
|
export function validateOptions({
|
||||||
|
|
|
@ -330,6 +330,11 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
||||||
defaultReadingTime: ReadingTimeFunction;
|
defaultReadingTime: ReadingTimeFunction;
|
||||||
},
|
},
|
||||||
) => number | undefined;
|
) => number | undefined;
|
||||||
|
|
||||||
|
export type ProcessBlogPostsFn = (params: {
|
||||||
|
blogPosts: BlogPost[];
|
||||||
|
}) => Promise<void | BlogPost[]>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugin options after normalization.
|
* Plugin options after normalization.
|
||||||
*/
|
*/
|
||||||
|
@ -421,6 +426,10 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
||||||
readingTime: ReadingTimeFunctionOption;
|
readingTime: ReadingTimeFunctionOption;
|
||||||
/** Governs the direction of blog post sorting. */
|
/** Governs the direction of blog post sorting. */
|
||||||
sortPosts: 'ascending' | 'descending';
|
sortPosts: 'ascending' | 'descending';
|
||||||
|
/** An optional function which can be used to transform blog posts
|
||||||
|
* (filter, modify, delete, etc...).
|
||||||
|
*/
|
||||||
|
processBlogPosts: ProcessBlogPostsFn;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -75,6 +75,7 @@ Accepted fields:
|
||||||
| `feedOptions.copyright` | `string` | `undefined` | Copyright message. |
|
| `feedOptions.copyright` | `string` | `undefined` | Copyright message. |
|
||||||
| `feedOptions.language` | `string` (See [documentation](http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes) for possible values) | `undefined` | Language metadata of the feed. |
|
| `feedOptions.language` | `string` (See [documentation](http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes) for possible values) | `undefined` | Language metadata of the feed. |
|
||||||
| `sortPosts` | <code>'descending' \| 'ascending' </code> | `'descending'` | Governs the direction of blog post sorting. |
|
| `sortPosts` | <code>'descending' \| 'ascending' </code> | `'descending'` | Governs the direction of blog post sorting. |
|
||||||
|
| `processBlogPosts` | <code>[ProcessBlogPostsFn](#ProcessBlogPostsFn)</code> | `undefined` | An optional function which can be used to transform blog posts (filter, modify, delete, etc...). |
|
||||||
|
|
||||||
```mdx-code-block
|
```mdx-code-block
|
||||||
</APITable>
|
</APITable>
|
||||||
|
@ -131,6 +132,14 @@ type CreateFeedItemsFn = (params: {
|
||||||
}) => Promise<BlogFeedItem[]>;
|
}) => Promise<BlogFeedItem[]>;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### `ProcessBlogPostsFn` {#ProcessBlogPostsFn}
|
||||||
|
|
||||||
|
```ts
|
||||||
|
type ProcessBlogPostsFn = (params: {
|
||||||
|
blogPosts: BlogPost[];
|
||||||
|
}) => Promise<void | BlogPost[]>;
|
||||||
|
```
|
||||||
|
|
||||||
### Example configuration {#ex-config}
|
### Example configuration {#ex-config}
|
||||||
|
|
||||||
You can configure this plugin through preset options or plugin options.
|
You can configure this plugin through preset options or plugin options.
|
||||||
|
|
|
@ -2977,6 +2977,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
|
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
|
||||||
integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
|
integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
|
||||||
|
|
||||||
|
"@total-typescript/shoehorn@^0.1.2":
|
||||||
|
version "0.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@total-typescript/shoehorn/-/shoehorn-0.1.2.tgz#a0c095ce8cb9b4ae3556bcff42702ddb072e9d18"
|
||||||
|
integrity sha512-p7nNZbOZIofpDNyP0u1BctFbjxD44Qc+oO5jufgQdFdGIXJLc33QRloJpq7k5T59CTgLWfQSUxsuqLcmeurYRw==
|
||||||
|
|
||||||
"@trysound/sax@0.2.0":
|
"@trysound/sax@0.2.0":
|
||||||
version "0.2.0"
|
version "0.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
|
resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
|
||||||
|
|
Loading…
Add table
Reference in a new issue