From 7a76d9b50ce1d36bfbedefce5e6b2fbf5cd70814 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 23 Feb 2024 21:10:19 +0100 Subject: [PATCH 01/17] feat(blog): allow process blog posts through a options.processBlogPosts function --- .../src/blogUtils.ts | 15 +++++++++++++++ .../docusaurus-plugin-content-blog/src/index.ts | 8 ++++++-- .../docusaurus-plugin-content-blog/src/options.ts | 4 ++++ .../src/plugin-content-blog.d.ts | 7 +++++++ website/docs/api/plugins/plugin-content-blog.mdx | 9 +++++++++ 5 files changed, 41 insertions(+), 2 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index e67e83345203..194971e985c0 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -446,3 +446,18 @@ export function linkify({ return newContent; } + +export async function applyProcessBlogPosts( + contentPaths: BlogContentPaths, + context: LoadContext, + options: PluginOptions, +): Promise { + const blogPosts = await generateBlogPosts(contentPaths, context, options); + const {processBlogPosts} = options; + const processedBlogPosts = processBlogPosts({blogPosts}); + + if (Array.isArray(processedBlogPosts)) { + return processedBlogPosts; + } + return blogPosts; +} diff --git a/packages/docusaurus-plugin-content-blog/src/index.ts b/packages/docusaurus-plugin-content-blog/src/index.ts index 35d6ac6b34db..20981fb1aebd 100644 --- a/packages/docusaurus-plugin-content-blog/src/index.ts +++ b/packages/docusaurus-plugin-content-blog/src/index.ts @@ -20,11 +20,11 @@ import { DEFAULT_PLUGIN_ID, } from '@docusaurus/utils'; import { - generateBlogPosts, getSourceToPermalink, getBlogTags, paginateBlogPosts, shouldBeListed, + applyProcessBlogPosts, } from './blogUtils'; import footnoteIDFixer from './remark/footnoteIDFixer'; import {translateContent, getTranslationFiles} from './translations'; @@ -113,7 +113,11 @@ export default async function pluginContentBlog( const baseBlogUrl = normalizeUrl([baseUrl, routeBasePath]); const blogTagsListPath = normalizeUrl([baseBlogUrl, tagsBasePath]); - const blogPosts = await generateBlogPosts(contentPaths, context, options); + const blogPosts = await applyProcessBlogPosts( + contentPaths, + context, + options, + ); const listedBlogPosts = blogPosts.filter(shouldBeListed); if (!blogPosts.length) { diff --git a/packages/docusaurus-plugin-content-blog/src/options.ts b/packages/docusaurus-plugin-content-blog/src/options.ts index d1e6e9cc4547..eb16c318d04d 100644 --- a/packages/docusaurus-plugin-content-blog/src/options.ts +++ b/packages/docusaurus-plugin-content-blog/src/options.ts @@ -51,6 +51,7 @@ export const DEFAULT_OPTIONS: PluginOptions = { authorsMapPath: 'authors.yml', readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}), sortPosts: 'descending', + processBlogPosts: () => undefined, }; const PluginOptionSchema = Joi.object({ @@ -134,6 +135,9 @@ const PluginOptionSchema = Joi.object({ sortPosts: Joi.string() .valid('descending', 'ascending') .default(DEFAULT_OPTIONS.sortPosts), + processBlogPosts: Joi.function() + .optional() + .default(() => DEFAULT_OPTIONS.processBlogPosts), }).default(DEFAULT_OPTIONS); export function validateOptions({ diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index f8b0bd3123ae..8da68a619674 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -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[]; + }) => void | BlogPost[]; + /** * Plugin options after normalization. */ @@ -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. */ + processBlogPosts: ProcessBlogPostsFn; }; /** diff --git a/website/docs/api/plugins/plugin-content-blog.mdx b/website/docs/api/plugins/plugin-content-blog.mdx index ec4332e5ff7b..7821f6f418e9 100644 --- a/website/docs/api/plugins/plugin-content-blog.mdx +++ b/website/docs/api/plugins/plugin-content-blog.mdx @@ -75,6 +75,7 @@ Accepted fields: | `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. | | `sortPosts` | 'descending' \| 'ascending' | `'descending'` | Governs the direction of blog post sorting. | +| `processBlogPosts` | ProcessBlogPostsFn | `undefined` | An optional function which can be used to transform blog posts (filter, modify, delete, etc...). | ```mdx-code-block @@ -131,6 +132,14 @@ type CreateFeedItemsFn = (params: { }) => Promise; ``` +#### `ProcessBlogPostsFn` {#ProcessBlogPostsFn} + +```ts +type ProcessBlogPostsFn = (params: { + blogPosts: BlogPost[]; +}) => void | BlogPost[]; +``` + ### Example configuration {#ex-config} You can configure this plugin through preset options or plugin options. From 29b29aee1722b7bd6881d2cb00cedc83d9e64b27 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Sat, 24 Feb 2024 02:00:03 +0100 Subject: [PATCH 02/17] wip: config option, test doesn't --- .../src/__tests__/blogUtils.test.ts | 50 ++++++++++++++++++- .../src/blogUtils.ts | 15 +++--- .../src/index.ts | 11 ++-- .../docs/api/plugins/plugin-content-blog.mdx | 2 +- 4 files changed, 64 insertions(+), 14 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts index d96f1228c897..fff1adb3955e 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts @@ -14,10 +14,11 @@ 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 {BlogPost, BlogPostMetadata} from '@docusaurus/plugin-content-blog'; describe('truncate', () => { it('truncates texts', () => { @@ -237,6 +238,7 @@ describe('linkify', () => { frontMatter: {}, authors: [], formattedDate: '', + unlisted: false, }, content: '', }, @@ -295,3 +297,49 @@ describe('linkify', () => { } as BlogBrokenMarkdownLink); }); }); + +const defaultValuesForOtherKeys: Omit = { + source: '', + title: '', + formattedDate: '', + permalink: '', + description: '', + hasTruncateMarker: false, + authors: [], + frontMatter: {}, + tags: [], + unlisted: false, +}; +const createBlogPost = (args: Partial): BlogPost => ({ + id: '', + metadata: { + date: new Date(), + ...defaultValuesForOtherKeys, + ...args.metadata, + }, + content: args.content || '', +}); + +describe('processBlogPosts', () => { + const blogPost2022 = createBlogPost({ + metadata: {date: new Date('2022-01-01'), ...defaultValuesForOtherKeys}, + }); + const blogPost2023 = createBlogPost({ + metadata: {date: new Date('2023-01-01'), ...defaultValuesForOtherKeys}, + }); + const blogPost2024 = createBlogPost({ + metadata: {date: new Date('2024-01-01'), ...defaultValuesForOtherKeys}, + }); + + it('filter blogs', async () => { + const processedBlogPosts = applyProcessBlogPosts({ + blogPosts: [blogPost2022, blogPost2023, blogPost2024], + processBlogPosts: ({blogPosts}: {blogPosts: BlogPost[]}) => + blogPosts.filter( + (blogPost) => blogPost.metadata.date.getFullYear() === 2024, + ), + }); + + expect(processedBlogPosts).toEqual([blogPost2024]); + }); +}); diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index 194971e985c0..4d9911c15ef5 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -447,17 +447,18 @@ export function linkify({ return newContent; } -export async function applyProcessBlogPosts( - contentPaths: BlogContentPaths, - context: LoadContext, - options: PluginOptions, -): Promise { - const blogPosts = await generateBlogPosts(contentPaths, context, options); - const {processBlogPosts} = options; +export async function applyProcessBlogPosts({ + blogPosts, + processBlogPosts, +}: { + blogPosts: BlogPost[]; + processBlogPosts: PluginOptions['processBlogPosts']; +}): Promise { const processedBlogPosts = processBlogPosts({blogPosts}); if (Array.isArray(processedBlogPosts)) { return processedBlogPosts; } + return blogPosts; } diff --git a/packages/docusaurus-plugin-content-blog/src/index.ts b/packages/docusaurus-plugin-content-blog/src/index.ts index 20981fb1aebd..eba91487779c 100644 --- a/packages/docusaurus-plugin-content-blog/src/index.ts +++ b/packages/docusaurus-plugin-content-blog/src/index.ts @@ -25,6 +25,7 @@ import { paginateBlogPosts, shouldBeListed, applyProcessBlogPosts, + generateBlogPosts, } from './blogUtils'; import footnoteIDFixer from './remark/footnoteIDFixer'; import {translateContent, getTranslationFiles} from './translations'; @@ -113,11 +114,11 @@ export default async function pluginContentBlog( const baseBlogUrl = normalizeUrl([baseUrl, routeBasePath]); const blogTagsListPath = normalizeUrl([baseBlogUrl, tagsBasePath]); - const blogPosts = await applyProcessBlogPosts( - 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) { diff --git a/website/docs/api/plugins/plugin-content-blog.mdx b/website/docs/api/plugins/plugin-content-blog.mdx index 7821f6f418e9..bb47401f6a76 100644 --- a/website/docs/api/plugins/plugin-content-blog.mdx +++ b/website/docs/api/plugins/plugin-content-blog.mdx @@ -137,7 +137,7 @@ type CreateFeedItemsFn = (params: { ```ts type ProcessBlogPostsFn = (params: { blogPosts: BlogPost[]; -}) => void | BlogPost[]; +}) => Promise; ``` ### Example configuration {#ex-config} From 3afcdfeed1ff69a0a2dc1d9c5a519f0fea3d83bf Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Mon, 26 Feb 2024 13:29:14 +0100 Subject: [PATCH 03/17] fix and try to improve tests --- .../src/__tests__/blogUtils.test.ts | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts index fff1adb3955e..dbefccf88078 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts @@ -18,7 +18,8 @@ import { type LinkifyParams, } from '../blogUtils'; import type {BlogBrokenMarkdownLink, BlogContentPaths} from '../types'; -import type {BlogPost, BlogPostMetadata} from '@docusaurus/plugin-content-blog'; +import type {BlogPost} from '@docusaurus/plugin-content-blog'; +import type {DeepPartial} from 'utility-types'; describe('truncate', () => { it('truncates texts', () => { @@ -298,23 +299,19 @@ describe('linkify', () => { }); }); -const defaultValuesForOtherKeys: Omit = { - source: '', - title: '', - formattedDate: '', - permalink: '', - description: '', - hasTruncateMarker: false, - authors: [], - frontMatter: {}, - tags: [], - unlisted: false, -}; -const createBlogPost = (args: Partial): BlogPost => ({ +const createBlogPost = (args: DeepPartial): BlogPost => ({ id: '', metadata: { - date: new Date(), - ...defaultValuesForOtherKeys, + source: '', + title: '', + formattedDate: '', + permalink: '', + description: '', + hasTruncateMarker: false, + authors: [], + frontMatter: {}, + tags: [], + unlisted: false, ...args.metadata, }, content: args.content || '', @@ -322,17 +319,17 @@ const createBlogPost = (args: Partial): BlogPost => ({ describe('processBlogPosts', () => { const blogPost2022 = createBlogPost({ - metadata: {date: new Date('2022-01-01'), ...defaultValuesForOtherKeys}, + metadata: {date: new Date('2022-01-01')}, }); const blogPost2023 = createBlogPost({ - metadata: {date: new Date('2023-01-01'), ...defaultValuesForOtherKeys}, + metadata: {date: new Date('2023-01-01')}, }); const blogPost2024 = createBlogPost({ - metadata: {date: new Date('2024-01-01'), ...defaultValuesForOtherKeys}, + metadata: {date: new Date('2024-01-01')}, }); - it('filter blogs', async () => { - const processedBlogPosts = applyProcessBlogPosts({ + it('filter only blogs from 2024', async () => { + const processedBlogPosts = await applyProcessBlogPosts({ blogPosts: [blogPost2022, blogPost2023, blogPost2024], processBlogPosts: ({blogPosts}: {blogPosts: BlogPost[]}) => blogPosts.filter( From 6019b81519f982a34f5972aa2f4563f2d42c3344 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Mon, 26 Feb 2024 16:51:16 +0100 Subject: [PATCH 04/17] fix type and add test --- .../src/__tests__/blogUtils.test.ts | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts index dbefccf88078..b6c5f23bdc90 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts @@ -313,7 +313,7 @@ const createBlogPost = (args: DeepPartial): BlogPost => ({ tags: [], unlisted: false, ...args.metadata, - }, + } as BlogPost['metadata'], content: args.content || '', }); @@ -328,7 +328,7 @@ describe('processBlogPosts', () => { metadata: {date: new Date('2024-01-01')}, }); - it('filter only blogs from 2024', async () => { + it('filter blogs only from 2024', async () => { const processedBlogPosts = await applyProcessBlogPosts({ blogPosts: [blogPost2022, blogPost2023, blogPost2024], processBlogPosts: ({blogPosts}: {blogPosts: BlogPost[]}) => @@ -339,4 +339,36 @@ describe('processBlogPosts', () => { expect(processedBlogPosts).toEqual([blogPost2024]); }); + + it('sort blogs by date in ascending order', async () => { + const processedBlogPosts = await applyProcessBlogPosts({ + blogPosts: [blogPost2023, blogPost2022, blogPost2024], + processBlogPosts: ({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: ({blogPosts}: {blogPosts: BlogPost[]}) => + blogPosts.sort( + (a, b) => b.metadata.date.getTime() - a.metadata.date.getTime(), + ), + }); + + expect(processedBlogPosts).toEqual([ + blogPost2024, + blogPost2023, + blogPost2022, + ]); + }); }); From 64e5f47b2fc356bc59971a458b85350dc4716622 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Mon, 26 Feb 2024 18:44:55 +0100 Subject: [PATCH 05/17] processBlogPosts async function & tests --- .../src/__tests__/blogUtils.test.ts | 28 +++++++++++++++++-- .../src/blogUtils.ts | 2 +- .../src/options.ts | 2 +- .../src/plugin-content-blog.d.ts | 2 +- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts index b6c5f23bdc90..67ed2c66c644 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts @@ -331,7 +331,7 @@ describe('processBlogPosts', () => { it('filter blogs only from 2024', async () => { const processedBlogPosts = await applyProcessBlogPosts({ blogPosts: [blogPost2022, blogPost2023, blogPost2024], - processBlogPosts: ({blogPosts}: {blogPosts: BlogPost[]}) => + processBlogPosts: async ({blogPosts}: {blogPosts: BlogPost[]}) => blogPosts.filter( (blogPost) => blogPost.metadata.date.getFullYear() === 2024, ), @@ -343,7 +343,7 @@ describe('processBlogPosts', () => { it('sort blogs by date in ascending order', async () => { const processedBlogPosts = await applyProcessBlogPosts({ blogPosts: [blogPost2023, blogPost2022, blogPost2024], - processBlogPosts: ({blogPosts}: {blogPosts: BlogPost[]}) => + processBlogPosts: async ({blogPosts}: {blogPosts: BlogPost[]}) => blogPosts.sort( (a, b) => a.metadata.date.getTime() - b.metadata.date.getTime(), ), @@ -359,7 +359,7 @@ describe('processBlogPosts', () => { it('sort blogs by date in descending order', async () => { const processedBlogPosts = await applyProcessBlogPosts({ blogPosts: [blogPost2023, blogPost2022, blogPost2024], - processBlogPosts: ({blogPosts}: {blogPosts: BlogPost[]}) => + processBlogPosts: async ({blogPosts}: {blogPosts: BlogPost[]}) => blogPosts.sort( (a, b) => b.metadata.date.getTime() - a.metadata.date.getTime(), ), @@ -371,4 +371,26 @@ describe('processBlogPosts', () => { 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, + ]); + }); }); diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index 4d9911c15ef5..7468ab345b26 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -454,7 +454,7 @@ export async function applyProcessBlogPosts({ blogPosts: BlogPost[]; processBlogPosts: PluginOptions['processBlogPosts']; }): Promise { - const processedBlogPosts = processBlogPosts({blogPosts}); + const processedBlogPosts = await processBlogPosts({blogPosts}); if (Array.isArray(processedBlogPosts)) { return processedBlogPosts; diff --git a/packages/docusaurus-plugin-content-blog/src/options.ts b/packages/docusaurus-plugin-content-blog/src/options.ts index eb16c318d04d..62e2a36c94d9 100644 --- a/packages/docusaurus-plugin-content-blog/src/options.ts +++ b/packages/docusaurus-plugin-content-blog/src/options.ts @@ -51,7 +51,7 @@ export const DEFAULT_OPTIONS: PluginOptions = { authorsMapPath: 'authors.yml', readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}), sortPosts: 'descending', - processBlogPosts: () => undefined, + processBlogPosts: async () => undefined, }; const PluginOptionSchema = Joi.object({ diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index 8da68a619674..fba10714c739 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -338,7 +338,7 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the export type ProcessBlogPostsFn = (params: { blogPosts: BlogPost[]; - }) => void | BlogPost[]; + }) => Promise; /** * Plugin options after normalization. From 0d8777c4846fd9ea8561dd626a9108a32c48c753 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 27 Feb 2024 00:18:04 +0100 Subject: [PATCH 06/17] wip: loadcontent test --- .../website-blog-with-dates/blog/date-2020.md | 7 +++ .../website-blog-with-dates/blog/date-2021.md | 7 +++ .../website-blog-with-dates/blog/date-2022.md | 7 +++ .../website-blog-with-dates/blog/date-2023.md | 7 +++ .../website-blog-with-dates/blog/date-2024.md | 7 +++ .../website-blog-with-dates/blog/date-2025.md | 7 +++ .../website-blog-with-dates/blog/date-2026.md | 7 +++ .../website-blog-with-dates/blog/date-2027.md | 7 +++ .../website-blog-with-dates/blog/date-2028.md | 7 +++ .../website-blog-with-dates/blog/date-2029.md | 7 +++ .../website-blog-with-dates/blog/date-2030.md | 7 +++ .../blog/date-2031-unlisted.md | 8 +++ .../__snapshots__/index.test.ts.snap | 60 +++++++++++++++++++ .../src/__tests__/index.test.ts | 15 +++++ 14 files changed, 160 insertions(+) create mode 100644 packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2020.md create mode 100644 packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2021.md create mode 100644 packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2022.md create mode 100644 packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2023.md create mode 100644 packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2024.md create mode 100644 packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2025.md create mode 100644 packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2026.md create mode 100644 packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2027.md create mode 100644 packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2028.md create mode 100644 packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2029.md create mode 100644 packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2030.md create mode 100644 packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2031-unlisted.md diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2020.md b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2020.md new file mode 100644 index 000000000000..54ba5ed81836 --- /dev/null +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2020.md @@ -0,0 +1,7 @@ +--- +slug: /date/2020 +title: 2020 +date: 2020-01-01 +--- + +2020 diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2021.md b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2021.md new file mode 100644 index 000000000000..7eeb2524f471 --- /dev/null +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2021.md @@ -0,0 +1,7 @@ +--- +slug: /date/2021 +title: 2021 +date: 2021-01-01 +--- + +2021 diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2022.md b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2022.md new file mode 100644 index 000000000000..14f49a9d484d --- /dev/null +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2022.md @@ -0,0 +1,7 @@ +--- +slug: /date/2022 +title: 2022 +date: 2022-01-01 +--- + +2022 diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2023.md b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2023.md new file mode 100644 index 000000000000..fa277d1051c0 --- /dev/null +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2023.md @@ -0,0 +1,7 @@ +--- +slug: /date/2023 +title: 2023 +date: 2023-01-01 +--- + +2023 diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2024.md b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2024.md new file mode 100644 index 000000000000..dca40f5ea42a --- /dev/null +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2024.md @@ -0,0 +1,7 @@ +--- +slug: /date/2024 +title: 2024 +date: 2024-01-01 +--- + +2024 diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2025.md b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2025.md new file mode 100644 index 000000000000..9adffa3661bb --- /dev/null +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2025.md @@ -0,0 +1,7 @@ +--- +slug: /date/2025 +title: 2025 +date: 2025-01-01 +--- + +2025 diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2026.md b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2026.md new file mode 100644 index 000000000000..4e7907bcf280 --- /dev/null +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2026.md @@ -0,0 +1,7 @@ +--- +slug: /date/2026 +title: 2026 +date: 2026-01-01 +--- + +2026 diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2027.md b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2027.md new file mode 100644 index 000000000000..eedc6e8d8404 --- /dev/null +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2027.md @@ -0,0 +1,7 @@ +--- +slug: /date/2027 +title: 2027 +date: 2027-01-01 +--- + +2027 diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2028.md b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2028.md new file mode 100644 index 000000000000..9de0329c196c --- /dev/null +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2028.md @@ -0,0 +1,7 @@ +--- +slug: /date/2028 +title: 2028 +date: 2028-01-01 +--- + +2028 diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2029.md b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2029.md new file mode 100644 index 000000000000..a861084be6c4 --- /dev/null +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2029.md @@ -0,0 +1,7 @@ +--- +slug: /date/2029 +title: 2029 +date: 2029-01-01 +--- + +2029 diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2030.md b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2030.md new file mode 100644 index 000000000000..cbfc5c5f86f1 --- /dev/null +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2030.md @@ -0,0 +1,7 @@ +--- +slug: /date/2030 +title: 2030 +date: 2030-01-01 +--- + +2030 diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2031-unlisted.md b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2031-unlisted.md new file mode 100644 index 000000000000..21b2921e7684 --- /dev/null +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website-blog-with-dates/blog/date-2031-unlisted.md @@ -0,0 +1,8 @@ +--- +slug: /date/2031 +title: 2031 +date: 2031-01-01 +unlisted: true +--- + +2031 diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap index b884dddfc605..606907854854 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap @@ -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", + "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": { diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts index 51b2f63f2fe7..a3585a9296d2 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts @@ -541,4 +541,19 @@ describe('blog plugin', () => { expect(blogTags).toMatchSnapshot(); }); + + it('process blog posts load content', async () => { + const siteDir = path.join( + __dirname, + '__fixtures__', + 'website-blog-with-dates', + ); + const processedBlogPosts = await getBlogPosts(siteDir, { + postsPerPage: 2, + processBlogPosts: async ({blogPosts}) => + blogPosts.filter((blog) => blog.metadata.date.getFullYear() > 2029), + }); + + expect(processedBlogPosts).toMatchSnapshot(); + }); }); From c7374078e18bbea9d4bdcf435b2ac5cb20db9f0a Mon Sep 17 00:00:00 2001 From: ozaki <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 23 Feb 2024 18:30:05 +0100 Subject: [PATCH 07/17] refactor(theme): dates should be formatted on the client-side instead of in nodejs code (#9868) Co-authored-by: OzakIOne Co-authored-by: sebastien --- .../src/__tests__/index.test.ts | 45 +------------------ .../src/blogUtils.ts | 25 ----------- .../src/plugin-content-blog.d.ts | 5 --- .../__snapshots__/index.test.ts.snap | 28 ------------ .../src/__tests__/docs.test.ts | 5 --- .../src/docs.ts | 24 ---------- .../src/plugin-content-docs.d.ts | 2 - .../src/theme-classic.d.ts | 1 - .../src/theme/BlogArchivePage/index.tsx | 12 ++++- .../theme/BlogPostItem/Header/Info/index.tsx | 27 +++++++++-- .../src/theme/DocItem/Footer/index.tsx | 8 +--- .../src/theme/LastUpdated/index.tsx | 31 +++++++------ .../docusaurus-theme-common/src/internal.ts | 1 + .../src/utils/IntlUtils.ts | 27 +++++++++++ project-words.txt | 4 -- 15 files changed, 83 insertions(+), 162 deletions(-) create mode 100644 packages/docusaurus-theme-common/src/utils/IntlUtils.ts diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts index a3585a9296d2..1090aa54a497 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts @@ -41,6 +41,7 @@ const markdown: MarkdownConfig = { } return result; }, + remarkRehypeOptions: undefined, }; function findByTitle( @@ -175,7 +176,6 @@ describe('blog plugin', () => { description: `date inside front matter`, authors: [], date: new Date('2019-01-01'), - formattedDate: 'January 1, 2019', frontMatter: { date: new Date('2019-01-01'), tags: ['date'], @@ -220,7 +220,6 @@ describe('blog plugin', () => { }, ], date: new Date('2018-12-14'), - formattedDate: 'December 14, 2018', frontMatter: { authors: [ { @@ -256,7 +255,6 @@ describe('blog plugin', () => { title: 'Simple Slug', }, date: new Date('2020-08-16'), - formattedDate: 'August 16, 2020', frontMatter: { date: '2020/08/16', slug: '/hey/my super path/héllô', @@ -302,7 +300,6 @@ describe('blog plugin', () => { title: 'draft', }, date: new Date('2020-08-15'), - formattedDate: 'August 15, 2020', frontMatter: { author: 'Sébastien Lorber', author_title: 'Docusaurus maintainer', @@ -328,7 +325,6 @@ describe('blog plugin', () => { description: '', authors: [], date: new Date('2019-01-02'), - formattedDate: 'January 2, 2019', frontMatter: { date: new Date('2019-01-02'), }, @@ -343,39 +339,6 @@ describe('blog plugin', () => { }); }); - it('builds simple website blog with localized dates', async () => { - const siteDir = path.join(__dirname, '__fixtures__', 'website'); - const blogPostsFrench = await getBlogPosts(siteDir, {}, getI18n('fr')); - expect(blogPostsFrench).toHaveLength(10); - expect(blogPostsFrench[0]!.metadata.formattedDate).toMatchInlineSnapshot( - `"23 juillet 2023"`, - ); - expect(blogPostsFrench[1]!.metadata.formattedDate).toMatchInlineSnapshot( - `"6 mars 2021"`, - ); - expect(blogPostsFrench[2]!.metadata.formattedDate).toMatchInlineSnapshot( - `"5 mars 2021"`, - ); - expect(blogPostsFrench[3]!.metadata.formattedDate).toMatchInlineSnapshot( - `"16 août 2020"`, - ); - expect(blogPostsFrench[4]!.metadata.formattedDate).toMatchInlineSnapshot( - `"15 août 2020"`, - ); - expect(blogPostsFrench[5]!.metadata.formattedDate).toMatchInlineSnapshot( - `"27 février 2020"`, - ); - expect(blogPostsFrench[6]!.metadata.formattedDate).toMatchInlineSnapshot( - `"27 février 2020"`, - ); - expect(blogPostsFrench[7]!.metadata.formattedDate).toMatchInlineSnapshot( - `"2 janvier 2019"`, - ); - expect(blogPostsFrench[8]!.metadata.formattedDate).toMatchInlineSnapshot( - `"1 janvier 2019"`, - ); - }); - it('handles edit URL with editLocalizedBlogs: true', async () => { const siteDir = path.join(__dirname, '__fixtures__', 'website'); const blogPosts = await getBlogPosts(siteDir, {editLocalizedFiles: true}); @@ -476,11 +439,6 @@ describe('blog plugin', () => { // We know the file exists and we know we have git const result = getFileCommitDate(noDateSourceFile, {age: 'oldest'}); const noDateSourceTime = result.date; - const formattedDate = Intl.DateTimeFormat('en', { - day: 'numeric', - month: 'long', - year: 'numeric', - }).format(noDateSourceTime); expect({ ...getByTitle(blogPosts, 'no date').metadata, @@ -494,7 +452,6 @@ describe('blog plugin', () => { description: `no date`, authors: [], date: noDateSourceTime, - formattedDate, frontMatter: {}, tags: [], prevItem: undefined, diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index 7468ab345b26..57cab065c743 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -164,25 +164,6 @@ export function parseBlogFileName( return {date: undefined, text, slug}; } -function formatBlogPostDate( - locale: string, - date: Date, - calendar: string, -): string { - try { - return new Intl.DateTimeFormat(locale, { - day: 'numeric', - month: 'long', - year: 'numeric', - timeZone: 'UTC', - calendar, - }).format(date); - } catch (err) { - logger.error`Can't format blog post date "${String(date)}"`; - throw err; - } -} - async function parseBlogPostMarkdownFile({ filePath, parseFrontMatter, @@ -289,11 +270,6 @@ async function processBlogSourceFile( } const date = await getDate(); - const formattedDate = formatBlogPostDate( - i18n.currentLocale, - date, - i18n.localeConfigs[i18n.currentLocale]!.calendar, - ); const title = frontMatter.title ?? contentTitle ?? parsedBlogFileName.text; const description = frontMatter.description ?? excerpt ?? ''; @@ -348,7 +324,6 @@ async function processBlogSourceFile( title, description, date, - formattedDate, tags: normalizeFrontMatterTags(tagsBasePath, frontMatter.tags), readingTime: showReadingTime ? options.readingTime({ diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index fba10714c739..4e26404aa92b 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -192,11 +192,6 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the * into a string. */ readonly date: Date; - /** - * Publish date formatted according to the locale, so that the client can - * render the date regardless of the existence of `Intl.DateTimeFormat`. - */ - readonly formattedDate: string; /** Full link including base URL. */ readonly permalink: string; /** diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap index 2a8b72873b07..2cacda09b97d 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap @@ -52,7 +52,6 @@ exports[`simple website content 1`] = ` "description": "Images", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": { "id": "baz", "pagination_label": "baz pagination_label", @@ -105,7 +104,6 @@ exports[`simple website content 2`] = ` "description": "Hi, Endilie here :)", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": { "id": "hello", "sidebar_label": "Hello sidebar_label", @@ -151,7 +149,6 @@ exports[`simple website content 3`] = ` "description": "This is custom description", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": { "description": "This is custom description", "id": "bar", @@ -1971,7 +1968,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha "description": "Getting started text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": {}, "id": "getting-started", "lastUpdatedAt": undefined, @@ -1999,7 +1995,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha "description": "Installation text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": {}, "id": "installation", "lastUpdatedAt": undefined, @@ -2030,7 +2025,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha "description": "Guide 1 text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": { "id": "guide1", "sidebar_position": 1, @@ -2064,7 +2058,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha "description": "Guide 2 text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": { "id": "guide2", }, @@ -2097,7 +2090,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha "description": "Guide 2.5 text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": { "id": "guide2.5", "sidebar_position": 2.5, @@ -2131,7 +2123,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha "description": "Guide 3 text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": { "id": "guide3", "sidebar_position": 3, @@ -2165,7 +2156,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha "description": "Guide 4 text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": { "id": "guide4", }, @@ -2198,7 +2188,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha "description": "Guide 5 text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": { "id": "guide5", }, @@ -2231,7 +2220,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha "description": "API Overview text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": {}, "id": "API/api-overview", "lastUpdatedAt": undefined, @@ -2262,7 +2250,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha "description": "Client API text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": {}, "id": "API/Core APIs/Client API", "lastUpdatedAt": undefined, @@ -2293,7 +2280,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha "description": "Server API text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": {}, "id": "API/Core APIs/Server API", "lastUpdatedAt": undefined, @@ -2324,7 +2310,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha "description": "Plugin API text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": {}, "id": "API/Extension APIs/Plugin API", "lastUpdatedAt": undefined, @@ -2355,7 +2340,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha "description": "Theme API text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": {}, "id": "API/Extension APIs/Theme API", "lastUpdatedAt": undefined, @@ -2386,7 +2370,6 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha "description": "API End text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": {}, "id": "API/api-end", "lastUpdatedAt": undefined, @@ -2566,7 +2549,6 @@ exports[`site with partial autogenerated sidebars docs in partially generated si "description": "API End text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": {}, "id": "API/api-end", "lastUpdatedAt": undefined, @@ -2594,7 +2576,6 @@ exports[`site with partial autogenerated sidebars docs in partially generated si "description": "API Overview text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": {}, "id": "API/api-overview", "lastUpdatedAt": undefined, @@ -2625,7 +2606,6 @@ exports[`site with partial autogenerated sidebars docs in partially generated si "description": "Plugin API text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": {}, "id": "API/Extension APIs/Plugin API", "lastUpdatedAt": undefined, @@ -2656,7 +2636,6 @@ exports[`site with partial autogenerated sidebars docs in partially generated si "description": "Theme API text", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": {}, "id": "API/Extension APIs/Theme API", "lastUpdatedAt": undefined, @@ -2716,7 +2695,6 @@ exports[`versioned website (community) content 1`] = ` "description": "Team current version (translated)", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": { "title": "Team title translated", }, @@ -2743,7 +2721,6 @@ exports[`versioned website (community) content 2`] = ` "description": "Team 1.0.0", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": {}, "id": "team", "lastUpdatedAt": undefined, @@ -3023,7 +3000,6 @@ exports[`versioned website content 1`] = ` "description": "This is next version of bar.", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": { "slug": "barSlug", "tags": [ @@ -3074,7 +3050,6 @@ exports[`versioned website content 2`] = ` "description": "Bar 1.0.1 !", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": {}, "id": "foo/bar", "lastUpdatedAt": undefined, @@ -3102,7 +3077,6 @@ exports[`versioned website content 3`] = ` "description": "Hello next !", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": { "slug": "/", }, @@ -3132,7 +3106,6 @@ exports[`versioned website content 4`] = ` "description": "Hello 1.0.1 !", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": { "slug": "/", }, @@ -3162,7 +3135,6 @@ exports[`versioned website content 5`] = ` "description": "Baz 1.0.0 ! This will be deleted in next subsequent versions.", "draft": false, "editUrl": undefined, - "formattedLastUpdatedAt": undefined, "frontMatter": {}, "id": "foo/baz", "lastUpdatedAt": undefined, diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts index 7309620d737c..a2c86b4d5935 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts @@ -475,7 +475,6 @@ describe('simple site', () => { unrelated_front_matter: "won't be part of metadata", }, lastUpdatedAt: 1539502055, - formattedLastUpdatedAt: 'Oct 14, 2018', lastUpdatedBy: 'Author', tags: [], unlisted: false, @@ -573,7 +572,6 @@ describe('simple site', () => { title: 'Custom Last Update', }, lastUpdatedAt: new Date('1/1/2000').getTime() / 1000, - formattedLastUpdatedAt: 'Jan 1, 2000', lastUpdatedBy: 'Custom Author (processed by parseFrontMatter)', sidebarPosition: undefined, tags: [], @@ -612,7 +610,6 @@ describe('simple site', () => { title: 'Last Update Author Only', }, lastUpdatedAt: 1539502055, - formattedLastUpdatedAt: 'Oct 14, 2018', lastUpdatedBy: 'Custom Author (processed by parseFrontMatter)', sidebarPosition: undefined, tags: [], @@ -651,7 +648,6 @@ describe('simple site', () => { title: 'Last Update Date Only', }, lastUpdatedAt: new Date('1/1/2000').getTime() / 1000, - formattedLastUpdatedAt: 'Jan 1, 2000', lastUpdatedBy: 'Author', sidebarPosition: undefined, tags: [], @@ -691,7 +687,6 @@ describe('simple site', () => { title: 'Custom Last Update', }, lastUpdatedAt: undefined, - formattedLastUpdatedAt: undefined, lastUpdatedBy: undefined, sidebarPosition: undefined, tags: [], diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 2907ac7211f3..158f949ef370 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -8,7 +8,6 @@ import path from 'path'; import fs from 'fs-extra'; import _ from 'lodash'; -import logger from '@docusaurus/logger'; import { aliasedSitePath, getEditUrl, @@ -142,7 +141,6 @@ async function doProcessDocMetadata({ const {source, content, contentPath, filePath} = docFile; const { siteDir, - i18n, siteConfig: { markdown: {parseFrontMatter}, }, @@ -257,21 +255,6 @@ async function doProcessDocMetadata({ const draft = isDraft({env, frontMatter}); const unlisted = isUnlisted({env, frontMatter}); - const formatDate = (locale: string, date: Date, calendar: string): string => { - try { - return new Intl.DateTimeFormat(locale, { - day: 'numeric', - month: 'short', - year: 'numeric', - timeZone: 'UTC', - calendar, - }).format(date); - } catch (err) { - logger.error`Can't format docs lastUpdatedAt date "${String(date)}"`; - throw err; - } - }; - // Assign all of object properties during instantiation (if possible) for // NodeJS optimization. // Adding properties to object after instantiation will cause hidden @@ -291,13 +274,6 @@ async function doProcessDocMetadata({ version: versionMetadata.versionName, lastUpdatedBy: lastUpdate.lastUpdatedBy, lastUpdatedAt: lastUpdate.lastUpdatedAt, - formattedLastUpdatedAt: lastUpdate.lastUpdatedAt - ? formatDate( - i18n.currentLocale, - new Date(lastUpdate.lastUpdatedAt * 1000), - i18n.localeConfigs[i18n.currentLocale]!.calendar, - ) - : undefined, sidebarPosition, frontMatter, }; diff --git a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts index 96f8fb3883a0..dc0db6e40368 100644 --- a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts +++ b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts @@ -407,8 +407,6 @@ declare module '@docusaurus/plugin-content-docs' { export type LastUpdateData = { /** A timestamp in **seconds**, directly acquired from `git log`. */ lastUpdatedAt?: number; - /** `lastUpdatedAt` formatted as a date according to the current locale. */ - formattedLastUpdatedAt?: string; /** The author's name directly acquired from `git log`. */ lastUpdatedBy?: string; }; diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index a54f0799a81e..6afed49abcfc 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -824,7 +824,6 @@ declare module '@theme/SearchMetadata' { declare module '@theme/LastUpdated' { export interface Props { readonly lastUpdatedAt?: number; - readonly formattedLastUpdatedAt?: string; readonly lastUpdatedBy?: string; } diff --git a/packages/docusaurus-theme-classic/src/theme/BlogArchivePage/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogArchivePage/index.tsx index 28613c6a462a..f4174faa91c2 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogArchivePage/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogArchivePage/index.tsx @@ -9,6 +9,7 @@ import React from 'react'; import Link from '@docusaurus/Link'; import {translate} from '@docusaurus/Translate'; import {PageMetadata} from '@docusaurus/theme-common'; +import {useDateTimeFormat} from '@docusaurus/theme-common/internal'; import Layout from '@theme/Layout'; import type {ArchiveBlogPost, Props} from '@theme/BlogArchivePage'; import Heading from '@theme/Heading'; @@ -19,6 +20,15 @@ type YearProp = { }; function Year({year, posts}: YearProp) { + const dateTimeFormat = useDateTimeFormat({ + day: 'numeric', + month: 'long', + timeZone: 'UTC', + }); + + const formatDate = (lastUpdated: string) => + dateTimeFormat.format(new Date(lastUpdated)); + return ( <> @@ -28,7 +38,7 @@ function Year({year, posts}: YearProp) { {posts.map((post) => (
  • - {post.metadata.formattedDate} - {post.metadata.title} + {formatDate(post.metadata.date)} - {post.metadata.title}
  • ))} diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Info/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Info/index.tsx index 22811b499ecc..9b5308bbc73a 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Info/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Info/index.tsx @@ -9,7 +9,10 @@ import React from 'react'; import clsx from 'clsx'; import {translate} from '@docusaurus/Translate'; import {usePluralForm} from '@docusaurus/theme-common'; -import {useBlogPost} from '@docusaurus/theme-common/internal'; +import { + useBlogPost, + useDateTimeFormat, +} from '@docusaurus/theme-common/internal'; import type {Props} from '@theme/BlogPostItem/Header/Info'; import styles from './styles.module.css'; @@ -39,7 +42,13 @@ function ReadingTime({readingTime}: {readingTime: number}) { return <>{readingTimePlural(readingTime)}; } -function Date({date, formattedDate}: {date: string; formattedDate: string}) { +function DateTime({ + date, + formattedDate, +}: { + date: string; + formattedDate: string; +}) { return ; } @@ -51,11 +60,21 @@ export default function BlogPostItemHeaderInfo({ className, }: Props): JSX.Element { const {metadata} = useBlogPost(); - const {date, formattedDate, readingTime} = metadata; + const {date, readingTime} = metadata; + + const dateTimeFormat = useDateTimeFormat({ + day: 'numeric', + month: 'long', + year: 'numeric', + timeZone: 'UTC', + }); + + const formatDate = (blogDate: string) => + dateTimeFormat.format(new Date(blogDate)); return (
    - + {typeof readingTime !== 'undefined' && ( <> diff --git a/packages/docusaurus-theme-classic/src/theme/DocItem/Footer/index.tsx b/packages/docusaurus-theme-classic/src/theme/DocItem/Footer/index.tsx index 971d7a8ff754..c59b85b3d49d 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocItem/Footer/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/DocItem/Footer/index.tsx @@ -33,13 +33,12 @@ function TagsRow(props: TagsListInlineProps) { type EditMetaRowProps = Pick< DocContextValue['metadata'], - 'editUrl' | 'lastUpdatedAt' | 'lastUpdatedBy' | 'formattedLastUpdatedAt' + 'editUrl' | 'lastUpdatedAt' | 'lastUpdatedBy' >; function EditMetaRow({ editUrl, lastUpdatedAt, lastUpdatedBy, - formattedLastUpdatedAt, }: EditMetaRowProps) { return (
    @@ -49,7 +48,6 @@ function EditMetaRow({ {(lastUpdatedAt || lastUpdatedBy) && ( )} @@ -60,8 +58,7 @@ function EditMetaRow({ export default function DocItemFooter(): JSX.Element | null { const {metadata} = useDoc(); - const {editUrl, lastUpdatedAt, formattedLastUpdatedAt, lastUpdatedBy, tags} = - metadata; + const {editUrl, lastUpdatedAt, lastUpdatedBy, tags} = metadata; const canDisplayTagsRow = tags.length > 0; const canDisplayEditMetaRow = !!(editUrl || lastUpdatedAt || lastUpdatedBy); @@ -81,7 +78,6 @@ export default function DocItemFooter(): JSX.Element | null { editUrl={editUrl} lastUpdatedAt={lastUpdatedAt} lastUpdatedBy={lastUpdatedBy} - formattedLastUpdatedAt={formattedLastUpdatedAt} /> )} diff --git a/packages/docusaurus-theme-classic/src/theme/LastUpdated/index.tsx b/packages/docusaurus-theme-classic/src/theme/LastUpdated/index.tsx index 5ba4c3e2f249..69ec6d1e2128 100644 --- a/packages/docusaurus-theme-classic/src/theme/LastUpdated/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/LastUpdated/index.tsx @@ -8,15 +8,25 @@ import React from 'react'; import Translate from '@docusaurus/Translate'; import {ThemeClassNames} from '@docusaurus/theme-common'; +import {useDateTimeFormat} from '@docusaurus/theme-common/internal'; import type {Props} from '@theme/LastUpdated'; function LastUpdatedAtDate({ lastUpdatedAt, - formattedLastUpdatedAt, }: { lastUpdatedAt: number; - formattedLastUpdatedAt: string; }): JSX.Element { + const atDate = new Date(lastUpdatedAt * 1000); + + const dateTimeFormat = useDateTimeFormat({ + day: 'numeric', + month: 'short', + year: 'numeric', + timeZone: 'UTC', + }); + + const formattedLastUpdatedAt = dateTimeFormat.format(atDate); + return ( -