From 426b8fcde66066fe0bfc84921d6233e1762bb675 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 9 Apr 2024 17:58:49 +0200 Subject: [PATCH 01/19] feat(pages): add support for last update date & author --- .../src/index.ts | 28 +++++++++++++++---- .../src/options.ts | 6 ++++ .../src/plugin-content-pages.d.ts | 4 +++ .../src/theme/MDXPage/index.tsx | 6 ++++ 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/packages/docusaurus-plugin-content-pages/src/index.ts b/packages/docusaurus-plugin-content-pages/src/index.ts index 7fe81e83af33..d27b24d26333 100644 --- a/packages/docusaurus-plugin-content-pages/src/index.ts +++ b/packages/docusaurus-plugin-content-pages/src/index.ts @@ -23,6 +23,7 @@ import { parseMarkdownFile, isUnlisted, isDraft, + readLastUpdateData, } from '@docusaurus/utils'; import {validatePageFrontMatter} from './frontMatter'; import type {LoadContext, Plugin, RouteMetadata} from '@docusaurus/types'; @@ -159,12 +160,27 @@ export default function pluginContentPages( const {addRoute, createData} = actions; - function createPageRouteMetadata(metadata: Metadata): RouteMetadata { + async function createPageRouteMetadata( + metadata: Metadata, + ): Promise { + if (metadata.type === 'mdx') { + const lastUpdate = await readLastUpdateData( + metadata.source, + options, + metadata.frontMatter.last_update, + ); + + return { + sourceFilePath: aliasedSitePathToRelativePath(metadata.source), + // TODO add support for last updated date in the page plugin + // at least for Markdown files + // lastUpdatedAt: metadata.lastUpdatedAt, + lastUpdatedAt: lastUpdate.lastUpdatedAt, + }; + } + return { sourceFilePath: aliasedSitePathToRelativePath(metadata.source), - // TODO add support for last updated date in the page plugin - // at least for Markdown files - // lastUpdatedAt: metadata.lastUpdatedAt, lastUpdatedAt: undefined, }; } @@ -184,7 +200,7 @@ export default function pluginContentPages( path: permalink, component: options.mdxPageComponent, exact: true, - metadata: routeMetadata, + metadata: await routeMetadata, modules: { content: source, }, @@ -194,7 +210,7 @@ export default function pluginContentPages( path: permalink, component: source, exact: true, - metadata: routeMetadata, + metadata: await routeMetadata, modules: { config: `@generated/docusaurus.config`, }, diff --git a/packages/docusaurus-plugin-content-pages/src/options.ts b/packages/docusaurus-plugin-content-pages/src/options.ts index 014f07f11980..3f85bd405b4b 100644 --- a/packages/docusaurus-plugin-content-pages/src/options.ts +++ b/packages/docusaurus-plugin-content-pages/src/options.ts @@ -27,6 +27,8 @@ export const DEFAULT_OPTIONS: PluginOptions = { beforeDefaultRehypePlugins: [], beforeDefaultRemarkPlugins: [], admonitions: true, + showLastUpdateTime: false, + showLastUpdateAuthor: false, }; const PluginOptionSchema = Joi.object({ @@ -44,6 +46,10 @@ const PluginOptionSchema = Joi.object({ DEFAULT_OPTIONS.beforeDefaultRemarkPlugins, ), admonitions: AdmonitionsSchema.default(DEFAULT_OPTIONS.admonitions), + showLastUpdateTime: Joi.bool().default(DEFAULT_OPTIONS.showLastUpdateTime), + showLastUpdateAuthor: Joi.bool().default( + DEFAULT_OPTIONS.showLastUpdateAuthor, + ), }); export function validateOptions({ diff --git a/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts b/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts index f0a9230cdee0..ec81280bb620 100644 --- a/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts +++ b/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts @@ -8,6 +8,7 @@ declare module '@docusaurus/plugin-content-pages' { import type {MDXOptions} from '@docusaurus/mdx-loader'; import type {LoadContext, Plugin} from '@docusaurus/types'; + import type {FrontMatterLastUpdate} from '@docusaurus/utils'; export type Assets = { image?: string; @@ -20,6 +21,8 @@ declare module '@docusaurus/plugin-content-pages' { include: string[]; exclude: string[]; mdxPageComponent: string; + showLastUpdateTime: boolean; + showLastUpdateAuthor: boolean; }; export type Options = Partial; @@ -35,6 +38,7 @@ declare module '@docusaurus/plugin-content-pages' { readonly toc_max_heading_level?: number; readonly draft?: boolean; readonly unlisted?: boolean; + readonly last_update?: FrontMatterLastUpdate; }; export type JSXPageMetadata = { diff --git a/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx b/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx index c9222ad0b532..328aa2a81637 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx @@ -30,6 +30,8 @@ export default function MDXPage(props: Props): JSX.Element { keywords, wrapperClassName, hide_table_of_contents: hideTableOfContents, + last_update: lastUpdate, + author, } = frontMatter; const image = assets.image ?? frontMatter.image; @@ -67,6 +69,10 @@ export default function MDXPage(props: Props): JSX.Element { )} +
Author 1 : {author as string}
+
Author 2 : {lastUpdate?.author}
+
Date : {String(lastUpdate?.date)}
+
Json : {JSON.stringify(frontMatter)}
); From af80172fc6eec9985ba8f574c7819fa7248d390a Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 10 Apr 2024 14:05:11 +0200 Subject: [PATCH 02/19] wip git last update not working --- .../src/theme/MDXPage/index.tsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx b/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx index 328aa2a81637..f2b62b2958ba 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx @@ -18,6 +18,7 @@ import TOC from '@theme/TOC'; import Unlisted from '@theme/Unlisted'; import type {Props} from '@theme/MDXPage'; +import EditMetaRow from '@theme/EditMetaRow'; import styles from './styles.module.css'; export default function MDXPage(props: Props): JSX.Element { @@ -31,7 +32,6 @@ export default function MDXPage(props: Props): JSX.Element { wrapperClassName, hide_table_of_contents: hideTableOfContents, last_update: lastUpdate, - author, } = frontMatter; const image = assets.image ?? frontMatter.image; @@ -68,11 +68,17 @@ export default function MDXPage(props: Props): JSX.Element { )} +
{JSON.stringify(frontMatter)}
+ -
Author 1 : {author as string}
-
Author 2 : {lastUpdate?.author}
-
Date : {String(lastUpdate?.date)}
-
Json : {JSON.stringify(frontMatter)}
); From 0c058f01a6081648671cdda1dca65d27af7d1ff0 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 10 Apr 2024 15:05:02 +0200 Subject: [PATCH 03/19] wip --- packages/docusaurus-plugin-content-pages/src/frontMatter.ts | 2 ++ packages/docusaurus-plugin-content-pages/src/index.ts | 1 + packages/docusaurus-plugin-content-pages/src/options.ts | 5 +++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/docusaurus-plugin-content-pages/src/frontMatter.ts b/packages/docusaurus-plugin-content-pages/src/frontMatter.ts index b87907adbd5f..5a87b1a221df 100644 --- a/packages/docusaurus-plugin-content-pages/src/frontMatter.ts +++ b/packages/docusaurus-plugin-content-pages/src/frontMatter.ts @@ -11,6 +11,7 @@ import { FrontMatterTOCHeadingLevels, ContentVisibilitySchema, URISchema, + FrontMatterLastUpdateSchema, } from '@docusaurus/utils-validation'; import type {PageFrontMatter} from '@docusaurus/plugin-content-pages'; @@ -24,6 +25,7 @@ const PageFrontMatterSchema = Joi.object({ wrapperClassName: Joi.string(), hide_table_of_contents: Joi.boolean(), ...FrontMatterTOCHeadingLevels, + last_update: FrontMatterLastUpdateSchema, }).concat(ContentVisibilitySchema); export function validatePageFrontMatter(frontMatter: { diff --git a/packages/docusaurus-plugin-content-pages/src/index.ts b/packages/docusaurus-plugin-content-pages/src/index.ts index d27b24d26333..fc83be652a0a 100644 --- a/packages/docusaurus-plugin-content-pages/src/index.ts +++ b/packages/docusaurus-plugin-content-pages/src/index.ts @@ -75,6 +75,7 @@ export default function pluginContentPages( async loadContent() { const {include} = options; + console.log('options:', options); if (!(await fs.pathExists(contentPaths.contentPath))) { return null; diff --git a/packages/docusaurus-plugin-content-pages/src/options.ts b/packages/docusaurus-plugin-content-pages/src/options.ts index 3f85bd405b4b..b1322003ebe6 100644 --- a/packages/docusaurus-plugin-content-pages/src/options.ts +++ b/packages/docusaurus-plugin-content-pages/src/options.ts @@ -27,8 +27,9 @@ export const DEFAULT_OPTIONS: PluginOptions = { beforeDefaultRehypePlugins: [], beforeDefaultRemarkPlugins: [], admonitions: true, - showLastUpdateTime: false, - showLastUpdateAuthor: false, + // TODO not working in config ?? + showLastUpdateTime: true, + showLastUpdateAuthor: true, }; const PluginOptionSchema = Joi.object({ From cd5223e697177894f8d47a7ec8cae18b80482f6a Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 10 Apr 2024 19:19:42 +0200 Subject: [PATCH 04/19] wip --- packages/docusaurus-plugin-content-pages/src/index.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/docusaurus-plugin-content-pages/src/index.ts b/packages/docusaurus-plugin-content-pages/src/index.ts index fc83be652a0a..2de3c4336585 100644 --- a/packages/docusaurus-plugin-content-pages/src/index.ts +++ b/packages/docusaurus-plugin-content-pages/src/index.ts @@ -75,7 +75,6 @@ export default function pluginContentPages( async loadContent() { const {include} = options; - console.log('options:', options); if (!(await fs.pathExists(contentPaths.contentPath))) { return null; @@ -166,11 +165,10 @@ export default function pluginContentPages( ): Promise { if (metadata.type === 'mdx') { const lastUpdate = await readLastUpdateData( - metadata.source, + aliasedSitePathToRelativePath(metadata.source), options, metadata.frontMatter.last_update, ); - return { sourceFilePath: aliasedSitePathToRelativePath(metadata.source), // TODO add support for last updated date in the page plugin @@ -189,7 +187,8 @@ export default function pluginContentPages( await Promise.all( content.map(async (metadata) => { const {permalink, source} = metadata; - const routeMetadata = createPageRouteMetadata(metadata); + const routeMetadata = await createPageRouteMetadata(metadata); + console.log('routeMetadata:', routeMetadata); if (metadata.type === 'mdx') { await createData( // Note that this created data path must be in sync with @@ -201,7 +200,7 @@ export default function pluginContentPages( path: permalink, component: options.mdxPageComponent, exact: true, - metadata: await routeMetadata, + metadata: routeMetadata, modules: { content: source, }, @@ -211,7 +210,7 @@ export default function pluginContentPages( path: permalink, component: source, exact: true, - metadata: await routeMetadata, + metadata: routeMetadata, modules: { config: `@generated/docusaurus.config`, }, From 5441315fbbb6bd5eed0acf26a55e831d3a09fb12 Mon Sep 17 00:00:00 2001 From: OzakIOne Date: Thu, 11 Apr 2024 14:54:46 +0000 Subject: [PATCH 05/19] refactor: apply lint autofix --- project-words.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/project-words.txt b/project-words.txt index 4338cda1e9d0..a8d6f78c1382 100644 --- a/project-words.txt +++ b/project-words.txt @@ -224,6 +224,7 @@ opensearch opensearchdescription opensource optimizt +Orama orama Orta orta From 432efc4de146215b1e1084d4e64a5a1c0386c64d Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 11 Apr 2024 18:18:19 +0200 Subject: [PATCH 06/19] feat: working --- .../src/index.ts | 19 +++++++++---------- .../src/plugin-content-pages.d.ts | 4 ++-- .../src/theme/MDXPage/index.tsx | 15 ++++++++++----- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/packages/docusaurus-plugin-content-pages/src/index.ts b/packages/docusaurus-plugin-content-pages/src/index.ts index 2de3c4336585..17df8c5f8334 100644 --- a/packages/docusaurus-plugin-content-pages/src/index.ts +++ b/packages/docusaurus-plugin-content-pages/src/index.ts @@ -121,6 +121,12 @@ export default function pluginContentPages( }); const frontMatter = validatePageFrontMatter(unsafeFrontMatter); + const lastUpdatedData = await readLastUpdateData( + source, + options, + frontMatter.last_update, + ); + if (isDraft({frontMatter})) { return undefined; } @@ -133,6 +139,8 @@ export default function pluginContentPages( title: frontMatter.title ?? contentTitle, description: frontMatter.description ?? excerpt, frontMatter, + lastUpdatedBy: lastUpdatedData.lastUpdatedBy, + lastUpdatedAt: lastUpdatedData.lastUpdatedAt, unlisted, }; } @@ -164,17 +172,9 @@ export default function pluginContentPages( metadata: Metadata, ): Promise { if (metadata.type === 'mdx') { - const lastUpdate = await readLastUpdateData( - aliasedSitePathToRelativePath(metadata.source), - options, - metadata.frontMatter.last_update, - ); return { sourceFilePath: aliasedSitePathToRelativePath(metadata.source), - // TODO add support for last updated date in the page plugin - // at least for Markdown files - // lastUpdatedAt: metadata.lastUpdatedAt, - lastUpdatedAt: lastUpdate.lastUpdatedAt, + lastUpdatedAt: metadata.lastUpdatedAt, }; } @@ -188,7 +188,6 @@ export default function pluginContentPages( content.map(async (metadata) => { const {permalink, source} = metadata; const routeMetadata = await createPageRouteMetadata(metadata); - console.log('routeMetadata:', routeMetadata); if (metadata.type === 'mdx') { await createData( // Note that this created data path must be in sync with diff --git a/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts b/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts index ec81280bb620..42234f60d7d6 100644 --- a/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts +++ b/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts @@ -8,7 +8,7 @@ declare module '@docusaurus/plugin-content-pages' { import type {MDXOptions} from '@docusaurus/mdx-loader'; import type {LoadContext, Plugin} from '@docusaurus/types'; - import type {FrontMatterLastUpdate} from '@docusaurus/utils'; + import type {FrontMatterLastUpdate, LastUpdateData} from '@docusaurus/utils'; export type Assets = { image?: string; @@ -47,7 +47,7 @@ declare module '@docusaurus/plugin-content-pages' { source: string; }; - export type MDXPageMetadata = { + export type MDXPageMetadata = LastUpdateData & { type: 'mdx'; permalink: string; source: string; diff --git a/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx b/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx index f2b62b2958ba..a497eab2f304 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx @@ -24,14 +24,20 @@ import styles from './styles.module.css'; export default function MDXPage(props: Props): JSX.Element { const {content: MDXPageContent} = props; const { - metadata: {title, description, frontMatter, unlisted}, + metadata: { + title, + description, + frontMatter, + unlisted, + lastUpdatedBy, + lastUpdatedAt, + }, assets, } = MDXPageContent; const { keywords, wrapperClassName, hide_table_of_contents: hideTableOfContents, - last_update: lastUpdate, } = frontMatter; const image = assets.image ?? frontMatter.image; @@ -68,15 +74,14 @@ export default function MDXPage(props: Props): JSX.Element { )} -
{JSON.stringify(frontMatter)}
From b18e6b4d715a3dd9a765413007e959416775b7be Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 11 Apr 2024 18:23:39 +0200 Subject: [PATCH 07/19] cleanup --- packages/docusaurus-plugin-content-pages/src/options.ts | 5 ++--- website/docusaurus.config.ts | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/docusaurus-plugin-content-pages/src/options.ts b/packages/docusaurus-plugin-content-pages/src/options.ts index b1322003ebe6..3f85bd405b4b 100644 --- a/packages/docusaurus-plugin-content-pages/src/options.ts +++ b/packages/docusaurus-plugin-content-pages/src/options.ts @@ -27,9 +27,8 @@ export const DEFAULT_OPTIONS: PluginOptions = { beforeDefaultRehypePlugins: [], beforeDefaultRemarkPlugins: [], admonitions: true, - // TODO not working in config ?? - showLastUpdateTime: true, - showLastUpdateAuthor: true, + showLastUpdateTime: false, + showLastUpdateAuthor: false, }; const PluginOptionSchema = Joi.object({ diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 04dec0dacb5e..410fba41cd0e 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -464,6 +464,8 @@ export default async function createConfigAsync() { } satisfies BlogOptions, pages: { remarkPlugins: [npm2yarn], + showLastUpdateAuthor: true, + showLastUpdateTime: true, } satisfies PageOptions, theme: { customCss: [ From b81ccfbacac24363d805fb8774ce5d253174c922 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 11 Apr 2024 18:39:54 +0200 Subject: [PATCH 08/19] fix layout shift --- .../src/theme/MDXPage/index.tsx | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx b/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx index a497eab2f304..23e0bef4abf2 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx @@ -41,6 +41,8 @@ export default function MDXPage(props: Props): JSX.Element { } = frontMatter; const image = assets.image ?? frontMatter.image; + const canDisplayEditMetaRow = !!(lastUpdatedAt || lastUpdatedBy); + return ( )} - + {canDisplayEditMetaRow && ( + + )} From 252d0f34f5bbff21a9e7ae5bc7138ffdf9850808 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 11 Apr 2024 19:34:32 +0200 Subject: [PATCH 09/19] wip --- .../src/index.ts | 62 +++++++++++++++---- .../src/options.ts | 4 ++ .../src/plugin-content-pages.d.ts | 17 +++++ .../src/theme/MDXPage/index.tsx | 5 +- .../src/utils/ThemeClassNames.ts | 3 + website/docusaurus.config.ts | 6 ++ 6 files changed, 82 insertions(+), 15 deletions(-) diff --git a/packages/docusaurus-plugin-content-pages/src/index.ts b/packages/docusaurus-plugin-content-pages/src/index.ts index 17df8c5f8334..6363fa1914c5 100644 --- a/packages/docusaurus-plugin-content-pages/src/index.ts +++ b/packages/docusaurus-plugin-content-pages/src/index.ts @@ -24,6 +24,8 @@ import { isUnlisted, isDraft, readLastUpdateData, + getEditUrl, + posixPath, } from '@docusaurus/utils'; import {validatePageFrontMatter} from './frontMatter'; import type {LoadContext, Plugin, RouteMetadata} from '@docusaurus/types'; @@ -46,7 +48,8 @@ export default function pluginContentPages( context: LoadContext, options: PluginOptions, ): Plugin { - const {siteConfig, siteDir, generatedFilesDir, localizationDir} = context; + const {siteConfig, siteDir, generatedFilesDir, localizationDir, i18n} = + context; const contentPaths: PagesContentPaths = { contentPath: path.resolve(siteDir, options.path), @@ -74,7 +77,7 @@ export default function pluginContentPages( }, async loadContent() { - const {include} = options; + const {include, editUrl} = options; if (!(await fs.pathExists(contentPaths.contentPath))) { return null; @@ -121,6 +124,44 @@ export default function pluginContentPages( }); const frontMatter = validatePageFrontMatter(unsafeFrontMatter); + const pagesDirPath = await getFolderContainingFile( + getContentPathList(contentPaths), + relativeSource, + ); + + const pagesSourceAbsolute = path.join(pagesDirPath, relativeSource); + + function getPagesEditUrl() { + const pagesPathRelative = path.relative( + pagesDirPath, + path.resolve(pagesSourceAbsolute), + ); + + if (typeof editUrl === 'function') { + return editUrl({ + pagesDirPath: posixPath(path.relative(siteDir, pagesDirPath)), + pagesPath: posixPath(pagesPathRelative), + permalink, + locale: i18n.currentLocale, + }); + } else if (typeof editUrl === 'string') { + const isLocalized = + pagesDirPath === contentPaths.contentPathLocalized; + const fileContentPath = + isLocalized && options.editLocalizedFiles + ? contentPaths.contentPathLocalized + : contentPaths.contentPath; + + const contentPathEditUrl = normalizeUrl([ + editUrl, + posixPath(path.relative(siteDir, fileContentPath)), + ]); + + return getEditUrl(pagesPathRelative, contentPathEditUrl); + } + return undefined; + } + const lastUpdatedData = await readLastUpdateData( source, options, @@ -141,6 +182,7 @@ export default function pluginContentPages( frontMatter, lastUpdatedBy: lastUpdatedData.lastUpdatedBy, lastUpdatedAt: lastUpdatedData.lastUpdatedAt, + editUrl: getPagesEditUrl(), unlisted, }; } @@ -168,26 +210,20 @@ export default function pluginContentPages( const {addRoute, createData} = actions; - async function createPageRouteMetadata( - metadata: Metadata, - ): Promise { - if (metadata.type === 'mdx') { - return { - sourceFilePath: aliasedSitePathToRelativePath(metadata.source), - lastUpdatedAt: metadata.lastUpdatedAt, - }; - } + function createPageRouteMetadata(metadata: Metadata): RouteMetadata { + const lastUpdatedAt = + metadata.type === 'mdx' ? metadata.lastUpdatedAt : undefined; return { sourceFilePath: aliasedSitePathToRelativePath(metadata.source), - lastUpdatedAt: undefined, + lastUpdatedAt, }; } await Promise.all( content.map(async (metadata) => { const {permalink, source} = metadata; - const routeMetadata = await createPageRouteMetadata(metadata); + const routeMetadata = createPageRouteMetadata(metadata); if (metadata.type === 'mdx') { await createData( // Note that this created data path must be in sync with diff --git a/packages/docusaurus-plugin-content-pages/src/options.ts b/packages/docusaurus-plugin-content-pages/src/options.ts index 3f85bd405b4b..88c3201b3008 100644 --- a/packages/docusaurus-plugin-content-pages/src/options.ts +++ b/packages/docusaurus-plugin-content-pages/src/options.ts @@ -11,6 +11,7 @@ import { RehypePluginsSchema, AdmonitionsSchema, RouteBasePathSchema, + URISchema, } from '@docusaurus/utils-validation'; import {GlobExcludeDefault} from '@docusaurus/utils'; import type {OptionValidationContext} from '@docusaurus/types'; @@ -29,6 +30,7 @@ export const DEFAULT_OPTIONS: PluginOptions = { admonitions: true, showLastUpdateTime: false, showLastUpdateAuthor: false, + editLocalizedFiles: false, }; const PluginOptionSchema = Joi.object({ @@ -50,6 +52,8 @@ const PluginOptionSchema = Joi.object({ showLastUpdateAuthor: Joi.bool().default( DEFAULT_OPTIONS.showLastUpdateAuthor, ), + editUrl: Joi.alternatives().try(URISchema, Joi.function()), + editLocalizedFiles: Joi.boolean().default(DEFAULT_OPTIONS.editLocalizedFiles), }); export function validateOptions({ diff --git a/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts b/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts index 42234f60d7d6..1c7b03743786 100644 --- a/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts +++ b/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts @@ -23,6 +23,8 @@ declare module '@docusaurus/plugin-content-pages' { mdxPageComponent: string; showLastUpdateTime: boolean; showLastUpdateAuthor: boolean; + editUrl?: string | EditUrlFunction; + editLocalizedFiles?: boolean; }; export type Options = Partial; @@ -52,11 +54,26 @@ declare module '@docusaurus/plugin-content-pages' { permalink: string; source: string; frontMatter: PageFrontMatter & {[key: string]: unknown}; + editUrl?: string; title?: string; description?: string; unlisted: boolean; }; + export type EditUrlFunction = (editUrlParams: { + /** + * The root content directory containing this post file, relative to the + * site path. Usually the same as `options.path` but can be localized + */ + pagesDirPath: string; + /** Path to this pages file, relative to `pagesDirPath`. */ + pagesPath: string; + /** @see {@link PagesPostMetadata.permalink} */ + permalink: string; + /** Locale name. */ + locale: string; + }) => string | undefined; + export type Metadata = JSXPageMetadata | MDXPageMetadata; export type LoadedContent = Metadata[]; diff --git a/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx b/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx index 23e0bef4abf2..0e55eaad4c64 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx @@ -26,6 +26,7 @@ export default function MDXPage(props: Props): JSX.Element { const { metadata: { title, + editUrl, description, frontMatter, unlisted, @@ -41,7 +42,7 @@ export default function MDXPage(props: Props): JSX.Element { } = frontMatter; const image = assets.image ?? frontMatter.image; - const canDisplayEditMetaRow = !!(lastUpdatedAt || lastUpdatedBy); + const canDisplayEditMetaRow = !!(editUrl || lastUpdatedAt || lastUpdatedBy); return ( diff --git a/packages/docusaurus-theme-common/src/utils/ThemeClassNames.ts b/packages/docusaurus-theme-common/src/utils/ThemeClassNames.ts index 79cf8e2ae0cf..1cdcda3ce50a 100644 --- a/packages/docusaurus-theme-common/src/utils/ThemeClassNames.ts +++ b/packages/docusaurus-theme-common/src/utils/ThemeClassNames.ts @@ -76,4 +76,7 @@ export const ThemeClassNames = { blogFooterTagsRow: 'theme-blog-footer-tags-row', blogFooterEditMetaRow: 'theme-blog-footer-edit-meta-row', }, + pages: { + pageFooterEditMetaRow: 'theme-pages-footer-edit-meta-row', + }, } as const; diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 410fba41cd0e..310ae8903bd5 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -464,6 +464,12 @@ export default async function createConfigAsync() { } satisfies BlogOptions, pages: { remarkPlugins: [npm2yarn], + editUrl: ({locale, pagesPath}) => { + if (locale !== defaultLocale) { + return `https://crowdin.com/project/docusaurus-v2/${locale}`; + } + return `https://github.com/facebook/docusaurus/edit/main/website/${pagesPath}`; + }, showLastUpdateAuthor: true, showLastUpdateTime: true, } satisfies PageOptions, From ac155df5b1fa53169dc96870f58e5c3fb06e7f44 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 11 Apr 2024 19:38:22 +0200 Subject: [PATCH 10/19] update link --- website/docusaurus.config.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 310ae8903bd5..4fc0171fa2de 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -468,7 +468,10 @@ export default async function createConfigAsync() { if (locale !== defaultLocale) { return `https://crowdin.com/project/docusaurus-v2/${locale}`; } - return `https://github.com/facebook/docusaurus/edit/main/website/${pagesPath}`; + // We want users to submit updates to the upstream/next version! + // Otherwise we risk losing the update on the next release. + const nextVersionDocsDirPath = 'src/pages'; + return `https://github.com/facebook/docusaurus/edit/main/website/${nextVersionDocsDirPath}/${pagesPath}`; }, showLastUpdateAuthor: true, showLastUpdateTime: true, From 47c50e64bef576a34669954ee24acfc032415826 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 12 Apr 2024 11:12:02 +0200 Subject: [PATCH 11/19] docs: add options --- .../docs/api/plugins/plugin-content-pages.mdx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/website/docs/api/plugins/plugin-content-pages.mdx b/website/docs/api/plugins/plugin-content-pages.mdx index 8894e7861b4c..9af38fb7d582 100644 --- a/website/docs/api/plugins/plugin-content-pages.mdx +++ b/website/docs/api/plugins/plugin-content-pages.mdx @@ -42,11 +42,27 @@ Accepted fields: | `rehypePlugins` | `[]` | `any[]` | Rehype plugins passed to MDX. | | `beforeDefaultRemarkPlugins` | `any[]` | `[]` | Custom Remark plugins passed to MDX before the default Docusaurus Remark plugins. | | `beforeDefaultRehypePlugins` | `any[]` | `[]` | Custom Rehype plugins passed to MDX before the default Docusaurus Rehype plugins. | +| `showLastUpdateAuthor` | `boolean` | `false` | Whether to display the author who last updated the page. | +| `showLastUpdateTime` | `boolean` | `false` | Whether to display the last date the page post was updated. This requires access to git history during the build, so will not work correctly with shallow clones (a common default for CI systems). With GitHub `actions/checkout`, use`fetch-depth: 0`. | +| `editUrl` | string \| [EditUrlFn](#EditUrlFn) | `undefined` | Base URL to edit your site. The final URL is computed by `editUrl + relativePostPath`. Using a function allows more nuanced control for each file. Omitting this variable entirely will disable edit links. | ```mdx-code-block ``` +### Types {#types} + +#### `EditUrlFn` {#EditUrlFn} + +```ts +type EditUrlFunction = (params: { + blogDirPath: string; + blogPath: string; + permalink: string; + locale: string; +}) => string | undefined; +``` + ### Example configuration {#ex-config} You can configure this plugin through preset options or plugin options. From 4811749a93f374d920b0787a0d6bd9fb8c14f57f Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 12 Apr 2024 11:30:24 +0200 Subject: [PATCH 12/19] tests: update & add new test --- .../__snapshots__/index.test.ts.snap | 87 +++++++++++++++++++ .../src/__tests__/index.test.ts | 20 +++++ 2 files changed, 107 insertions(+) diff --git a/packages/docusaurus-plugin-content-pages/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-pages/src/__tests__/__snapshots__/index.test.ts.snap index fc5fa2196778..bc9b5308c3eb 100644 --- a/packages/docusaurus-plugin-content-pages/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-pages/src/__tests__/__snapshots__/index.test.ts.snap @@ -14,9 +14,12 @@ exports[`docusaurus-plugin-content-pages loads simple pages 1`] = ` }, { "description": "Markdown index page", + "editUrl": undefined, "frontMatter": { "custom_frontMatter": "added by parseFrontMatter", }, + "lastUpdatedAt": undefined, + "lastUpdatedBy": undefined, "permalink": "/hello/", "source": "@site/src/pages/hello/index.md", "title": "Index", @@ -25,11 +28,14 @@ exports[`docusaurus-plugin-content-pages loads simple pages 1`] = ` }, { "description": "my MDX page", + "editUrl": undefined, "frontMatter": { "custom_frontMatter": "added by parseFrontMatter", "description": "my MDX page", "title": "MDX page", }, + "lastUpdatedAt": undefined, + "lastUpdatedBy": undefined, "permalink": "/hello/mdxPage", "source": "@site/src/pages/hello/mdxPage.mdx", "title": "MDX page", @@ -43,9 +49,12 @@ exports[`docusaurus-plugin-content-pages loads simple pages 1`] = ` }, { "description": "translated Markdown page", + "editUrl": undefined, "frontMatter": { "custom_frontMatter": "added by parseFrontMatter", }, + "lastUpdatedAt": undefined, + "lastUpdatedBy": undefined, "permalink": "/hello/translatedMd", "source": "@site/src/pages/hello/translatedMd.md", "title": undefined, @@ -74,9 +83,12 @@ exports[`docusaurus-plugin-content-pages loads simple pages with french translat }, { "description": "Markdown index page", + "editUrl": undefined, "frontMatter": { "custom_frontMatter": "added by parseFrontMatter", }, + "lastUpdatedAt": undefined, + "lastUpdatedBy": undefined, "permalink": "/fr/hello/", "source": "@site/src/pages/hello/index.md", "title": "Index", @@ -85,11 +97,14 @@ exports[`docusaurus-plugin-content-pages loads simple pages with french translat }, { "description": "my MDX page", + "editUrl": undefined, "frontMatter": { "custom_frontMatter": "added by parseFrontMatter", "description": "my MDX page", "title": "MDX page", }, + "lastUpdatedAt": undefined, + "lastUpdatedBy": undefined, "permalink": "/fr/hello/mdxPage", "source": "@site/src/pages/hello/mdxPage.mdx", "title": "MDX page", @@ -103,9 +118,12 @@ exports[`docusaurus-plugin-content-pages loads simple pages with french translat }, { "description": "translated Markdown page (fr)", + "editUrl": undefined, "frontMatter": { "custom_frontMatter": "added by parseFrontMatter", }, + "lastUpdatedAt": undefined, + "lastUpdatedBy": undefined, "permalink": "/fr/hello/translatedMd", "source": "@site/i18n/fr/docusaurus-plugin-content-pages/hello/translatedMd.md", "title": undefined, @@ -119,3 +137,72 @@ exports[`docusaurus-plugin-content-pages loads simple pages with french translat }, ] `; + +exports[`docusaurus-plugin-content-pages loads simple pages with last update 1`] = ` +[ + { + "permalink": "/", + "source": "@site/src/pages/index.js", + "type": "jsx", + }, + { + "permalink": "/typescript", + "source": "@site/src/pages/typescript.tsx", + "type": "jsx", + }, + { + "description": "Markdown index page", + "editUrl": "url placeholder", + "frontMatter": { + "custom_frontMatter": "added by parseFrontMatter", + }, + "lastUpdatedAt": 1539502055000, + "lastUpdatedBy": "Author", + "permalink": "/hello/", + "source": "@site/src/pages/hello/index.md", + "title": "Index", + "type": "mdx", + "unlisted": false, + }, + { + "description": "my MDX page", + "editUrl": "url placeholder", + "frontMatter": { + "custom_frontMatter": "added by parseFrontMatter", + "description": "my MDX page", + "title": "MDX page", + }, + "lastUpdatedAt": 1539502055000, + "lastUpdatedBy": "Author", + "permalink": "/hello/mdxPage", + "source": "@site/src/pages/hello/mdxPage.mdx", + "title": "MDX page", + "type": "mdx", + "unlisted": false, + }, + { + "permalink": "/hello/translatedJs", + "source": "@site/src/pages/hello/translatedJs.js", + "type": "jsx", + }, + { + "description": "translated Markdown page", + "editUrl": "url placeholder", + "frontMatter": { + "custom_frontMatter": "added by parseFrontMatter", + }, + "lastUpdatedAt": 1539502055000, + "lastUpdatedBy": "Author", + "permalink": "/hello/translatedMd", + "source": "@site/src/pages/hello/translatedMd.md", + "title": undefined, + "type": "mdx", + "unlisted": false, + }, + { + "permalink": "/hello/world", + "source": "@site/src/pages/hello/world.js", + "type": "jsx", + }, +] +`; diff --git a/packages/docusaurus-plugin-content-pages/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-pages/src/__tests__/index.test.ts index 5527f11e5ad0..24870c77bccb 100644 --- a/packages/docusaurus-plugin-content-pages/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-pages/src/__tests__/index.test.ts @@ -46,4 +46,24 @@ describe('docusaurus-plugin-content-pages', () => { expect(pagesMetadata).toMatchSnapshot(); }); + + it('loads simple pages with last update', async () => { + const siteDir = path.join(__dirname, '__fixtures__', 'website'); + const context = await loadContext({siteDir}); + const plugin = pluginContentPages( + context, + validateOptions({ + validate: normalizePluginOptions, + options: { + path: 'src/pages', + editUrl: () => 'url placeholder', + showLastUpdateAuthor: true, + showLastUpdateTime: true, + }, + }), + ); + const pagesMetadata = await plugin.loadContent!(); + + expect(pagesMetadata).toMatchSnapshot(); + }); }); From e735aa1a995ad7d764aa96c3ee4f68cee72065c3 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 12 Apr 2024 12:26:24 +0200 Subject: [PATCH 13/19] wip fix css layout --- .../src/theme/MDXPage/index.tsx | 22 +++++++++---------- website/_dogfooding/dogfooding.config.ts | 3 +++ 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx b/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx index 0e55eaad4c64..82cd9accf8ad 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx @@ -76,18 +76,18 @@ export default function MDXPage(props: Props): JSX.Element { /> )} + {canDisplayEditMetaRow && ( + + )} - {canDisplayEditMetaRow && ( - - )} diff --git a/website/_dogfooding/dogfooding.config.ts b/website/_dogfooding/dogfooding.config.ts index 3e57c13c36ad..e04d22fb331d 100644 --- a/website/_dogfooding/dogfooding.config.ts +++ b/website/_dogfooding/dogfooding.config.ts @@ -90,6 +90,9 @@ export const dogfoodingPluginInstances: PluginConfig[] = [ id: 'pages-tests', path: '_dogfooding/_pages tests', routeBasePath: '/tests/pages', + showLastUpdateTime: true, + showLastUpdateAuthor: true, + editUrl: () => 'url placeholder', } satisfies PageOptions, ], From c39a8989da07072e11ffd46de303095aac3bd737 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 12 Apr 2024 12:44:11 +0200 Subject: [PATCH 14/19] review --- website/docs/api/plugins/plugin-content-pages.mdx | 3 ++- website/docusaurus.config.ts | 5 +---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/website/docs/api/plugins/plugin-content-pages.mdx b/website/docs/api/plugins/plugin-content-pages.mdx index 9af38fb7d582..af81578ac42c 100644 --- a/website/docs/api/plugins/plugin-content-pages.mdx +++ b/website/docs/api/plugins/plugin-content-pages.mdx @@ -34,6 +34,8 @@ Accepted fields: | Name | Type | Default | Description | | --- | --- | --- | --- | | `path` | `string` | `'src/pages'` | Path to data on filesystem relative to site dir. Components in this directory will be automatically converted to pages. | +| `editUrl` | string \| [EditUrlFn](#EditUrlFn) | `undefined` | Base URL to edit your site. The final URL is computed by `editUrl + relativePostPath`. Using a function allows more nuanced control for each file. Omitting this variable entirely will disable edit links. | +| `editLocalizedFiles` | `boolean` | `false` | The edit URL will target the localized file, instead of the original unlocalized file. Ignored when `editUrl` is a function. | | `routeBasePath` | `string` | `'/'` | URL route for the pages section of your site. **DO NOT** include a trailing slash. | | `include` | `string[]` | `['**/*.{js,jsx,ts,tsx,md,mdx}']` | Matching files will be included and processed. | | `exclude` | `string[]` | _See example configuration_ | No route will be created for matching files. | @@ -44,7 +46,6 @@ Accepted fields: | `beforeDefaultRehypePlugins` | `any[]` | `[]` | Custom Rehype plugins passed to MDX before the default Docusaurus Rehype plugins. | | `showLastUpdateAuthor` | `boolean` | `false` | Whether to display the author who last updated the page. | | `showLastUpdateTime` | `boolean` | `false` | Whether to display the last date the page post was updated. This requires access to git history during the build, so will not work correctly with shallow clones (a common default for CI systems). With GitHub `actions/checkout`, use`fetch-depth: 0`. | -| `editUrl` | string \| [EditUrlFn](#EditUrlFn) | `undefined` | Base URL to edit your site. The final URL is computed by `editUrl + relativePostPath`. Using a function allows more nuanced control for each file. Omitting this variable entirely will disable edit links. | ```mdx-code-block diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 4fc0171fa2de..a5cdb17b4ae1 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -468,10 +468,7 @@ export default async function createConfigAsync() { if (locale !== defaultLocale) { return `https://crowdin.com/project/docusaurus-v2/${locale}`; } - // We want users to submit updates to the upstream/next version! - // Otherwise we risk losing the update on the next release. - const nextVersionDocsDirPath = 'src/pages'; - return `https://github.com/facebook/docusaurus/edit/main/website/${nextVersionDocsDirPath}/${pagesPath}`; + return `https://github.com/facebook/docusaurus/edit/main/website/src/pages/${pagesPath}`; }, showLastUpdateAuthor: true, showLastUpdateTime: true, From ebb35f6001c374369c185a18432ede37d6962fd7 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 12 Apr 2024 13:08:31 +0200 Subject: [PATCH 15/19] wip extract getItemEditURL to utils --- .../src/index.ts | 68 +++++++++++-------- .../src/plugin-content-pages.d.ts | 20 ++---- packages/docusaurus-utils/src/index.ts | 2 + packages/docusaurus-utils/src/urlUtils.ts | 66 ++++++++++++++++++ 4 files changed, 111 insertions(+), 45 deletions(-) diff --git a/packages/docusaurus-plugin-content-pages/src/index.ts b/packages/docusaurus-plugin-content-pages/src/index.ts index 6363fa1914c5..d21f910de006 100644 --- a/packages/docusaurus-plugin-content-pages/src/index.ts +++ b/packages/docusaurus-plugin-content-pages/src/index.ts @@ -24,8 +24,7 @@ import { isUnlisted, isDraft, readLastUpdateData, - getEditUrl, - posixPath, + getItemEditUrl, } from '@docusaurus/utils'; import {validatePageFrontMatter} from './frontMatter'; import type {LoadContext, Plugin, RouteMetadata} from '@docusaurus/types'; @@ -131,36 +130,36 @@ export default function pluginContentPages( const pagesSourceAbsolute = path.join(pagesDirPath, relativeSource); - function getPagesEditUrl() { - const pagesPathRelative = path.relative( - pagesDirPath, - path.resolve(pagesSourceAbsolute), - ); + // function getPagesEditUrl() { + // const pagesPathRelative = path.relative( + // pagesDirPath, + // path.resolve(pagesSourceAbsolute), + // ); - if (typeof editUrl === 'function') { - return editUrl({ - pagesDirPath: posixPath(path.relative(siteDir, pagesDirPath)), - pagesPath: posixPath(pagesPathRelative), - permalink, - locale: i18n.currentLocale, - }); - } else if (typeof editUrl === 'string') { - const isLocalized = - pagesDirPath === contentPaths.contentPathLocalized; - const fileContentPath = - isLocalized && options.editLocalizedFiles - ? contentPaths.contentPathLocalized - : contentPaths.contentPath; + // if (typeof editUrl === 'function') { + // return editUrl({ + // pagesDirPath: posixPath(path.relative(siteDir, pagesDirPath)), + // pagesPath: posixPath(pagesPathRelative), + // permalink, + // locale: i18n.currentLocale, + // }); + // } else if (typeof editUrl === 'string') { + // const isLocalized = + // pagesDirPath === contentPaths.contentPathLocalized; + // const fileContentPath = + // isLocalized && options.editLocalizedFiles + // ? contentPaths.contentPathLocalized + // : contentPaths.contentPath; - const contentPathEditUrl = normalizeUrl([ - editUrl, - posixPath(path.relative(siteDir, fileContentPath)), - ]); + // const contentPathEditUrl = normalizeUrl([ + // editUrl, + // posixPath(path.relative(siteDir, fileContentPath)), + // ]); - return getEditUrl(pagesPathRelative, contentPathEditUrl); - } - return undefined; - } + // return getEditUrl(pagesPathRelative, contentPathEditUrl); + // } + // return undefined; + // } const lastUpdatedData = await readLastUpdateData( source, @@ -182,7 +181,16 @@ export default function pluginContentPages( frontMatter, lastUpdatedBy: lastUpdatedData.lastUpdatedBy, lastUpdatedAt: lastUpdatedData.lastUpdatedAt, - editUrl: getPagesEditUrl(), + editUrl: getItemEditUrl({ + editUrl, + itemDirPath: pagesDirPath, + itemSourceAbsolute: pagesSourceAbsolute, + permalink, + i18n, + options, + siteDir, + contentPaths, + }), unlisted, }; } diff --git a/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts b/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts index 1c7b03743786..c88682abfeda 100644 --- a/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts +++ b/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts @@ -8,7 +8,11 @@ declare module '@docusaurus/plugin-content-pages' { import type {MDXOptions} from '@docusaurus/mdx-loader'; import type {LoadContext, Plugin} from '@docusaurus/types'; - import type {FrontMatterLastUpdate, LastUpdateData} from '@docusaurus/utils'; + import type { + FrontMatterLastUpdate, + LastUpdateData, + EditUrlFunction, + } from '@docusaurus/utils'; export type Assets = { image?: string; @@ -60,20 +64,6 @@ declare module '@docusaurus/plugin-content-pages' { unlisted: boolean; }; - export type EditUrlFunction = (editUrlParams: { - /** - * The root content directory containing this post file, relative to the - * site path. Usually the same as `options.path` but can be localized - */ - pagesDirPath: string; - /** Path to this pages file, relative to `pagesDirPath`. */ - pagesPath: string; - /** @see {@link PagesPostMetadata.permalink} */ - permalink: string; - /** Locale name. */ - locale: string; - }) => string | undefined; - export type Metadata = JSXPageMetadata | MDXPageMetadata; export type LoadedContent = Metadata[]; diff --git a/packages/docusaurus-utils/src/index.ts b/packages/docusaurus-utils/src/index.ts index 405da5258dd4..8fb385dd4a8a 100644 --- a/packages/docusaurus-utils/src/index.ts +++ b/packages/docusaurus-utils/src/index.ts @@ -48,6 +48,8 @@ export { hasSSHProtocol, buildHttpsUrl, buildSshUrl, + getItemEditUrl, + type EditUrlFunction, } from './urlUtils'; export type {URLPath} from './urlUtils'; export { diff --git a/packages/docusaurus-utils/src/urlUtils.ts b/packages/docusaurus-utils/src/urlUtils.ts index ddfc04272c36..eca22116b41b 100644 --- a/packages/docusaurus-utils/src/urlUtils.ts +++ b/packages/docusaurus-utils/src/urlUtils.ts @@ -5,7 +5,11 @@ * LICENSE file in the root directory of this source tree. */ +import path from 'path'; import resolvePathnameUnsafe from 'resolve-pathname'; +import {posixPath} from './pathUtils'; +import type {I18n, PluginOptions} from '@docusaurus/types'; +import type {ContentPaths} from './markdownLinks'; /** * Much like `path.join`, but much better. Takes an array of URL segments, and @@ -274,3 +278,65 @@ export function hasSSHProtocol(sourceRepoUrl: string): boolean { return /^(?:[\w-]+@)?[\w.-]+:[\w./-]+/.test(sourceRepoUrl); } } + +export type EditUrlFunction = (editUrlParams: { + /** + * The root content directory containing this post file, relative to the + * site path. Usually the same as `options.path` but can be localized + */ + itemDirPath: string; + /** Path to this item file, relative to `pagesDirPath`. */ + itemPath: string; + /** @see {@link PagesPostMetadata.permalink} */ + permalink: string; + /** Locale name. */ + locale: string; +}) => string | undefined; + +export function getItemEditUrl({ + siteDir, + contentPaths, + itemDirPath, + itemSourceAbsolute, + editUrl, + permalink, + i18n, + options, +}: { + siteDir: string; + contentPaths: ContentPaths; + itemDirPath: string; + itemSourceAbsolute: string; + editUrl: string | EditUrlFunction | undefined; + permalink: string; + i18n: I18n; + options: PluginOptions; +}): string | undefined { + const itemPathRelative = path.relative( + itemDirPath, + path.resolve(itemSourceAbsolute), + ); + + if (typeof editUrl === 'function') { + return editUrl({ + itemDirPath: posixPath(path.relative(siteDir, itemDirPath)), + itemPath: posixPath(itemPathRelative), + permalink, + locale: i18n.currentLocale, + }); + } else if (typeof editUrl === 'string') { + const isLocalized = itemDirPath === contentPaths.contentPathLocalized; + const fileContentPath = + isLocalized && options.editLocalizedFiles + ? contentPaths.contentPathLocalized + : contentPaths.contentPath; + + const contentPathEditUrl = normalizeUrl([ + editUrl, + posixPath(path.relative(siteDir, fileContentPath)), + ]); + + return getEditUrl(itemPathRelative, contentPathEditUrl); + } + return undefined; +} From 89b4cf7d2ae3d4db7439ecccc8e8bdcd3651047a Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 12 Apr 2024 16:41:16 +0200 Subject: [PATCH 16/19] Revert "wip extract getItemEditURL to utils" This reverts commit ebb35f6001c374369c185a18432ede37d6962fd7. --- .../src/index.ts | 68 ++++++++----------- .../src/plugin-content-pages.d.ts | 20 ++++-- packages/docusaurus-utils/src/index.ts | 2 - packages/docusaurus-utils/src/urlUtils.ts | 66 ------------------ 4 files changed, 45 insertions(+), 111 deletions(-) diff --git a/packages/docusaurus-plugin-content-pages/src/index.ts b/packages/docusaurus-plugin-content-pages/src/index.ts index d21f910de006..6363fa1914c5 100644 --- a/packages/docusaurus-plugin-content-pages/src/index.ts +++ b/packages/docusaurus-plugin-content-pages/src/index.ts @@ -24,7 +24,8 @@ import { isUnlisted, isDraft, readLastUpdateData, - getItemEditUrl, + getEditUrl, + posixPath, } from '@docusaurus/utils'; import {validatePageFrontMatter} from './frontMatter'; import type {LoadContext, Plugin, RouteMetadata} from '@docusaurus/types'; @@ -130,36 +131,36 @@ export default function pluginContentPages( const pagesSourceAbsolute = path.join(pagesDirPath, relativeSource); - // function getPagesEditUrl() { - // const pagesPathRelative = path.relative( - // pagesDirPath, - // path.resolve(pagesSourceAbsolute), - // ); + function getPagesEditUrl() { + const pagesPathRelative = path.relative( + pagesDirPath, + path.resolve(pagesSourceAbsolute), + ); - // if (typeof editUrl === 'function') { - // return editUrl({ - // pagesDirPath: posixPath(path.relative(siteDir, pagesDirPath)), - // pagesPath: posixPath(pagesPathRelative), - // permalink, - // locale: i18n.currentLocale, - // }); - // } else if (typeof editUrl === 'string') { - // const isLocalized = - // pagesDirPath === contentPaths.contentPathLocalized; - // const fileContentPath = - // isLocalized && options.editLocalizedFiles - // ? contentPaths.contentPathLocalized - // : contentPaths.contentPath; + if (typeof editUrl === 'function') { + return editUrl({ + pagesDirPath: posixPath(path.relative(siteDir, pagesDirPath)), + pagesPath: posixPath(pagesPathRelative), + permalink, + locale: i18n.currentLocale, + }); + } else if (typeof editUrl === 'string') { + const isLocalized = + pagesDirPath === contentPaths.contentPathLocalized; + const fileContentPath = + isLocalized && options.editLocalizedFiles + ? contentPaths.contentPathLocalized + : contentPaths.contentPath; - // const contentPathEditUrl = normalizeUrl([ - // editUrl, - // posixPath(path.relative(siteDir, fileContentPath)), - // ]); + const contentPathEditUrl = normalizeUrl([ + editUrl, + posixPath(path.relative(siteDir, fileContentPath)), + ]); - // return getEditUrl(pagesPathRelative, contentPathEditUrl); - // } - // return undefined; - // } + return getEditUrl(pagesPathRelative, contentPathEditUrl); + } + return undefined; + } const lastUpdatedData = await readLastUpdateData( source, @@ -181,16 +182,7 @@ export default function pluginContentPages( frontMatter, lastUpdatedBy: lastUpdatedData.lastUpdatedBy, lastUpdatedAt: lastUpdatedData.lastUpdatedAt, - editUrl: getItemEditUrl({ - editUrl, - itemDirPath: pagesDirPath, - itemSourceAbsolute: pagesSourceAbsolute, - permalink, - i18n, - options, - siteDir, - contentPaths, - }), + editUrl: getPagesEditUrl(), unlisted, }; } diff --git a/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts b/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts index c88682abfeda..1c7b03743786 100644 --- a/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts +++ b/packages/docusaurus-plugin-content-pages/src/plugin-content-pages.d.ts @@ -8,11 +8,7 @@ declare module '@docusaurus/plugin-content-pages' { import type {MDXOptions} from '@docusaurus/mdx-loader'; import type {LoadContext, Plugin} from '@docusaurus/types'; - import type { - FrontMatterLastUpdate, - LastUpdateData, - EditUrlFunction, - } from '@docusaurus/utils'; + import type {FrontMatterLastUpdate, LastUpdateData} from '@docusaurus/utils'; export type Assets = { image?: string; @@ -64,6 +60,20 @@ declare module '@docusaurus/plugin-content-pages' { unlisted: boolean; }; + export type EditUrlFunction = (editUrlParams: { + /** + * The root content directory containing this post file, relative to the + * site path. Usually the same as `options.path` but can be localized + */ + pagesDirPath: string; + /** Path to this pages file, relative to `pagesDirPath`. */ + pagesPath: string; + /** @see {@link PagesPostMetadata.permalink} */ + permalink: string; + /** Locale name. */ + locale: string; + }) => string | undefined; + export type Metadata = JSXPageMetadata | MDXPageMetadata; export type LoadedContent = Metadata[]; diff --git a/packages/docusaurus-utils/src/index.ts b/packages/docusaurus-utils/src/index.ts index 8fb385dd4a8a..405da5258dd4 100644 --- a/packages/docusaurus-utils/src/index.ts +++ b/packages/docusaurus-utils/src/index.ts @@ -48,8 +48,6 @@ export { hasSSHProtocol, buildHttpsUrl, buildSshUrl, - getItemEditUrl, - type EditUrlFunction, } from './urlUtils'; export type {URLPath} from './urlUtils'; export { diff --git a/packages/docusaurus-utils/src/urlUtils.ts b/packages/docusaurus-utils/src/urlUtils.ts index eca22116b41b..ddfc04272c36 100644 --- a/packages/docusaurus-utils/src/urlUtils.ts +++ b/packages/docusaurus-utils/src/urlUtils.ts @@ -5,11 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import path from 'path'; import resolvePathnameUnsafe from 'resolve-pathname'; -import {posixPath} from './pathUtils'; -import type {I18n, PluginOptions} from '@docusaurus/types'; -import type {ContentPaths} from './markdownLinks'; /** * Much like `path.join`, but much better. Takes an array of URL segments, and @@ -278,65 +274,3 @@ export function hasSSHProtocol(sourceRepoUrl: string): boolean { return /^(?:[\w-]+@)?[\w.-]+:[\w./-]+/.test(sourceRepoUrl); } } - -export type EditUrlFunction = (editUrlParams: { - /** - * The root content directory containing this post file, relative to the - * site path. Usually the same as `options.path` but can be localized - */ - itemDirPath: string; - /** Path to this item file, relative to `pagesDirPath`. */ - itemPath: string; - /** @see {@link PagesPostMetadata.permalink} */ - permalink: string; - /** Locale name. */ - locale: string; -}) => string | undefined; - -export function getItemEditUrl({ - siteDir, - contentPaths, - itemDirPath, - itemSourceAbsolute, - editUrl, - permalink, - i18n, - options, -}: { - siteDir: string; - contentPaths: ContentPaths; - itemDirPath: string; - itemSourceAbsolute: string; - editUrl: string | EditUrlFunction | undefined; - permalink: string; - i18n: I18n; - options: PluginOptions; -}): string | undefined { - const itemPathRelative = path.relative( - itemDirPath, - path.resolve(itemSourceAbsolute), - ); - - if (typeof editUrl === 'function') { - return editUrl({ - itemDirPath: posixPath(path.relative(siteDir, itemDirPath)), - itemPath: posixPath(itemPathRelative), - permalink, - locale: i18n.currentLocale, - }); - } else if (typeof editUrl === 'string') { - const isLocalized = itemDirPath === contentPaths.contentPathLocalized; - const fileContentPath = - isLocalized && options.editLocalizedFiles - ? contentPaths.contentPathLocalized - : contentPaths.contentPath; - - const contentPathEditUrl = normalizeUrl([ - editUrl, - posixPath(path.relative(siteDir, fileContentPath)), - ]); - - return getEditUrl(itemPathRelative, contentPathEditUrl); - } - return undefined; -} From 7e5f2c2774b5b2ed9b8c122c537d3d0be46616f8 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 12 Apr 2024 17:00:19 +0200 Subject: [PATCH 17/19] update url --- website/_dogfooding/dogfooding.config.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/_dogfooding/dogfooding.config.ts b/website/_dogfooding/dogfooding.config.ts index e04d22fb331d..ebb6b22885c9 100644 --- a/website/_dogfooding/dogfooding.config.ts +++ b/website/_dogfooding/dogfooding.config.ts @@ -92,7 +92,8 @@ export const dogfoodingPluginInstances: PluginConfig[] = [ routeBasePath: '/tests/pages', showLastUpdateTime: true, showLastUpdateAuthor: true, - editUrl: () => 'url placeholder', + editUrl: ({pagesPath}) => + `https://github.com/facebook/docusaurus/edit/main/website/_dogfooding/_pages tests/${pagesPath}`, } satisfies PageOptions, ], From c31227da541c4c4a15ffb70033ca36c2d4e45f9e Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Mon, 15 Apr 2024 16:30:29 +0200 Subject: [PATCH 18/19] fix layout style --- .../src/theme/MDXPage/index.tsx | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx b/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx index 82cd9accf8ad..103dc3e69a1b 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx @@ -66,6 +66,17 @@ export default function MDXPage(props: Props): JSX.Element { + {canDisplayEditMetaRow && ( + + )} {!hideTableOfContents && MDXPageContent.toc.length > 0 && (
@@ -76,17 +87,6 @@ export default function MDXPage(props: Props): JSX.Element { />
)} - {canDisplayEditMetaRow && ( - - )} From 287bf0bbe7c7cd686f2820f217bc9c580ae4e1ef Mon Sep 17 00:00:00 2001 From: sebastien Date: Mon, 15 Apr 2024 19:04:22 +0200 Subject: [PATCH 19/19] mention feature will only work for markdown pages --- website/docs/api/plugins/plugin-content-pages.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docs/api/plugins/plugin-content-pages.mdx b/website/docs/api/plugins/plugin-content-pages.mdx index af81578ac42c..266c929d5a14 100644 --- a/website/docs/api/plugins/plugin-content-pages.mdx +++ b/website/docs/api/plugins/plugin-content-pages.mdx @@ -34,8 +34,8 @@ Accepted fields: | Name | Type | Default | Description | | --- | --- | --- | --- | | `path` | `string` | `'src/pages'` | Path to data on filesystem relative to site dir. Components in this directory will be automatically converted to pages. | -| `editUrl` | string \| [EditUrlFn](#EditUrlFn) | `undefined` | Base URL to edit your site. The final URL is computed by `editUrl + relativePostPath`. Using a function allows more nuanced control for each file. Omitting this variable entirely will disable edit links. | -| `editLocalizedFiles` | `boolean` | `false` | The edit URL will target the localized file, instead of the original unlocalized file. Ignored when `editUrl` is a function. | +| `editUrl` | string \| [EditUrlFn](#EditUrlFn) | `undefined` | **Only for Markdown pages**. Base URL to edit your site. The final URL is computed by `editUrl + relativePostPath`. Using a function allows more nuanced control for each file. Omitting this variable entirely will disable edit links. | +| `editLocalizedFiles` | `boolean` | `false` | **Only for Markdown pages**. The edit URL will target the localized file, instead of the original unlocalized file. Ignored when `editUrl` is a function. | | `routeBasePath` | `string` | `'/'` | URL route for the pages section of your site. **DO NOT** include a trailing slash. | | `include` | `string[]` | `['**/*.{js,jsx,ts,tsx,md,mdx}']` | Matching files will be included and processed. | | `exclude` | `string[]` | _See example configuration_ | No route will be created for matching files. | @@ -44,8 +44,8 @@ Accepted fields: | `rehypePlugins` | `[]` | `any[]` | Rehype plugins passed to MDX. | | `beforeDefaultRemarkPlugins` | `any[]` | `[]` | Custom Remark plugins passed to MDX before the default Docusaurus Remark plugins. | | `beforeDefaultRehypePlugins` | `any[]` | `[]` | Custom Rehype plugins passed to MDX before the default Docusaurus Rehype plugins. | -| `showLastUpdateAuthor` | `boolean` | `false` | Whether to display the author who last updated the page. | -| `showLastUpdateTime` | `boolean` | `false` | Whether to display the last date the page post was updated. This requires access to git history during the build, so will not work correctly with shallow clones (a common default for CI systems). With GitHub `actions/checkout`, use`fetch-depth: 0`. | +| `showLastUpdateAuthor` | `boolean` | `false` | **Only for Markdown pages**. Whether to display the author who last updated the page. | +| `showLastUpdateTime` | `boolean` | `false` | **Only for Markdown pages**. Whether to display the last date the page post was updated. This requires access to git history during the build, so will not work correctly with shallow clones (a common default for CI systems). With GitHub `actions/checkout`, use`fetch-depth: 0`. | ```mdx-code-block