mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-21 13:06:58 +02:00
feat(v2): add a banner that links to latest version of documentation (#2916)
* feat(v2): add metadata to indicate the document is old * feat(v2): add badge that links old versions to latest version * feat(v2): fix test related to metadata * feat(v2): fix formatting * feat(v2): fix formatting * feat(v2): use Link component instead of anchor tag * feat(v2): add pramlink to latest docs * feat(v2): add more vibrant warning message * feat(v2): position the banner above the article * feat(v2): link latest version to intro page * fix(v2): fix some test cases * feat(v2): fix tests * feat(v2): change banner to warning orange * feat(v2): compute root route from sidebar * style(v2): fix formatting * feat(v2): use homeid if provided to compute base route * feat(v2): rename functions and fix a corner case * feat(v2): fix formating * feat(v2): compute homepageurl * style(v2): improve code quality * style(v2): unbold fullstop for consistency Co-authored-by: Anshul Goyal <anshulgoel151999@gmail.com>
This commit is contained in:
parent
d365b7424b
commit
0c92f5aacd
5 changed files with 72 additions and 2 deletions
|
@ -163,6 +163,7 @@ describe('simple website', () => {
|
||||||
source: path.join('@site', pluginPath, 'hello.md'),
|
source: path.join('@site', pluginPath, 'hello.md'),
|
||||||
title: 'Hello, World !',
|
title: 'Hello, World !',
|
||||||
description: 'Hi, Endilie here :)',
|
description: 'Hi, Endilie here :)',
|
||||||
|
latestVersionMainDocPermalink: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(docsMetadata['foo/bar']).toEqual({
|
expect(docsMetadata['foo/bar']).toEqual({
|
||||||
|
@ -176,6 +177,7 @@ describe('simple website', () => {
|
||||||
source: path.join('@site', pluginPath, 'foo', 'bar.md'),
|
source: path.join('@site', pluginPath, 'foo', 'bar.md'),
|
||||||
title: 'Bar',
|
title: 'Bar',
|
||||||
description: 'This is custom description',
|
description: 'This is custom description',
|
||||||
|
latestVersionMainDocPermalink: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(docsSidebars).toMatchSnapshot();
|
expect(docsSidebars).toMatchSnapshot();
|
||||||
|
@ -335,6 +337,7 @@ describe('versioned website', () => {
|
||||||
title: 'bar',
|
title: 'bar',
|
||||||
permalink: '/docs/foo/bar',
|
permalink: '/docs/foo/bar',
|
||||||
},
|
},
|
||||||
|
latestVersionMainDocPermalink: undefined,
|
||||||
});
|
});
|
||||||
expect(docsMetadata['version-1.0.0/foo/baz']).toEqual({
|
expect(docsMetadata['version-1.0.0/foo/baz']).toEqual({
|
||||||
id: 'version-1.0.0/foo/baz',
|
id: 'version-1.0.0/foo/baz',
|
||||||
|
|
|
@ -50,6 +50,7 @@ describe('simple site', () => {
|
||||||
source: path.join('@site', routeBasePath, sourceA),
|
source: path.join('@site', routeBasePath, sourceA),
|
||||||
title: 'Bar',
|
title: 'Bar',
|
||||||
description: 'This is custom description',
|
description: 'This is custom description',
|
||||||
|
latestVersionMainDocPermalink: undefined,
|
||||||
});
|
});
|
||||||
expect(dataB).toEqual({
|
expect(dataB).toEqual({
|
||||||
id: 'hello',
|
id: 'hello',
|
||||||
|
@ -57,6 +58,7 @@ describe('simple site', () => {
|
||||||
source: path.join('@site', routeBasePath, sourceB),
|
source: path.join('@site', routeBasePath, sourceB),
|
||||||
title: 'Hello, World !',
|
title: 'Hello, World !',
|
||||||
description: `Hi, Endilie here :)`,
|
description: `Hi, Endilie here :)`,
|
||||||
|
latestVersionMainDocPermalink: undefined,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -85,6 +87,7 @@ describe('simple site', () => {
|
||||||
editUrl:
|
editUrl:
|
||||||
'https://github.com/facebook/docusaurus/edit/master/website/docs/foo/baz.md',
|
'https://github.com/facebook/docusaurus/edit/master/website/docs/foo/baz.md',
|
||||||
description: 'Images',
|
description: 'Images',
|
||||||
|
latestVersionMainDocPermalink: undefined,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -109,6 +112,7 @@ describe('simple site', () => {
|
||||||
title: 'lorem',
|
title: 'lorem',
|
||||||
editUrl: 'https://github.com/customUrl/docs/lorem.md',
|
editUrl: 'https://github.com/customUrl/docs/lorem.md',
|
||||||
description: 'Lorem ipsum.',
|
description: 'Lorem ipsum.',
|
||||||
|
latestVersionMainDocPermalink: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
// unrelated frontmatter is not part of metadata
|
// unrelated frontmatter is not part of metadata
|
||||||
|
@ -140,6 +144,7 @@ describe('simple site', () => {
|
||||||
description: 'Lorem ipsum.',
|
description: 'Lorem ipsum.',
|
||||||
lastUpdatedAt: 1539502055,
|
lastUpdatedAt: 1539502055,
|
||||||
lastUpdatedBy: 'Author',
|
lastUpdatedBy: 'Author',
|
||||||
|
latestVersionMainDocPermalink: undefined,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -168,6 +173,7 @@ describe('simple site', () => {
|
||||||
description: 'Lorem ipsum.',
|
description: 'Lorem ipsum.',
|
||||||
lastUpdatedAt: 1539502055,
|
lastUpdatedAt: 1539502055,
|
||||||
lastUpdatedBy: 'Author',
|
lastUpdatedBy: 'Author',
|
||||||
|
latestVersionMainDocPermalink: undefined,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,22 @@ const DEFAULT_OPTIONS: PluginOptions = {
|
||||||
admonitions: {},
|
admonitions: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function getFirstDocLinkOfSidebar(
|
||||||
|
sidebarItems: DocsSidebarItem[],
|
||||||
|
): string | null {
|
||||||
|
for (let sidebarItem of sidebarItems) {
|
||||||
|
if (sidebarItem.type === 'category') {
|
||||||
|
const url = getFirstDocLinkOfSidebar(sidebarItem.items);
|
||||||
|
if (url) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return sidebarItem.href;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
export default function pluginContentDocs(
|
export default function pluginContentDocs(
|
||||||
context: LoadContext,
|
context: LoadContext,
|
||||||
opts: Partial<PluginOptions>,
|
opts: Partial<PluginOptions>,
|
||||||
|
@ -320,7 +336,6 @@ Available document ids=
|
||||||
},
|
},
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
docsMetadata,
|
docsMetadata,
|
||||||
docsDir,
|
docsDir,
|
||||||
|
@ -368,7 +383,6 @@ Available document ids=
|
||||||
const isDocsHomePage =
|
const isDocsHomePage =
|
||||||
metadataItem.id.replace(versionsRegex, '').replace(/^\//, '') ===
|
metadataItem.id.replace(versionsRegex, '').replace(/^\//, '') ===
|
||||||
options.homePageId;
|
options.homePageId;
|
||||||
|
|
||||||
if (isDocsHomePage) {
|
if (isDocsHomePage) {
|
||||||
const versionDocsPathPrefix =
|
const versionDocsPathPrefix =
|
||||||
(metadataItem?.version === versioning.latestVersion
|
(metadataItem?.version === versioning.latestVersion
|
||||||
|
@ -384,6 +398,7 @@ Available document ids=
|
||||||
homePageDocsRoutePath,
|
homePageDocsRoutePath,
|
||||||
versionDocsPathPrefix,
|
versionDocsPathPrefix,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const docsBaseMetadataPath = await createData(
|
const docsBaseMetadataPath = await createData(
|
||||||
`${docuHash(metadataItem.source)}-base.json`,
|
`${docuHash(metadataItem.source)}-base.json`,
|
||||||
JSON.stringify(docsBaseMetadata, null, 2),
|
JSON.stringify(docsBaseMetadata, null, 2),
|
||||||
|
@ -461,6 +476,22 @@ Available document ids=
|
||||||
Object.values(content.docsMetadata),
|
Object.values(content.docsMetadata),
|
||||||
'version',
|
'version',
|
||||||
);
|
);
|
||||||
|
const rootUrl =
|
||||||
|
options.homePageId && content.docsMetadata[options.homePageId]
|
||||||
|
? normalizeUrl([baseUrl, routeBasePath])
|
||||||
|
: getFirstDocLinkOfSidebar(
|
||||||
|
content.docsSidebars[
|
||||||
|
`version-${versioning.latestVersion}/docs`
|
||||||
|
],
|
||||||
|
);
|
||||||
|
if (!rootUrl) {
|
||||||
|
throw new Error('Bad sidebars file. No document linked');
|
||||||
|
}
|
||||||
|
Object.values(content.docsMetadata).forEach((docMetadata) => {
|
||||||
|
if (docMetadata.version !== versioning.latestVersion) {
|
||||||
|
docMetadata.latestVersionMainDocPermalink = rootUrl;
|
||||||
|
}
|
||||||
|
});
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
Object.keys(docsMetadataByVersion).map(async (version) => {
|
Object.keys(docsMetadataByVersion).map(async (version) => {
|
||||||
const routes: RouteConfig[] = await genRoutes(
|
const routes: RouteConfig[] = await genRoutes(
|
||||||
|
|
|
@ -118,6 +118,7 @@ export interface MetadataRaw extends LastUpdateData {
|
||||||
sidebar_label?: string;
|
sidebar_label?: string;
|
||||||
editUrl?: string;
|
editUrl?: string;
|
||||||
version?: string;
|
version?: string;
|
||||||
|
latestVersionMainDocPermalink?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Paginator {
|
export interface Paginator {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||||
import DocPaginator from '@theme/DocPaginator';
|
import DocPaginator from '@theme/DocPaginator';
|
||||||
import useTOCHighlight from '@theme/hooks/useTOCHighlight';
|
import useTOCHighlight from '@theme/hooks/useTOCHighlight';
|
||||||
|
import Link from '@docusaurus/Link';
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
|
@ -68,6 +69,7 @@ function DocItem(props) {
|
||||||
lastUpdatedAt,
|
lastUpdatedAt,
|
||||||
lastUpdatedBy,
|
lastUpdatedBy,
|
||||||
version,
|
version,
|
||||||
|
latestVersionMainDocPermalink,
|
||||||
} = metadata;
|
} = metadata;
|
||||||
const {
|
const {
|
||||||
frontMatter: {
|
frontMatter: {
|
||||||
|
@ -108,6 +110,33 @@ function DocItem(props) {
|
||||||
className={clsx('col', {
|
className={clsx('col', {
|
||||||
[styles.docItemCol]: !hideTableOfContents,
|
[styles.docItemCol]: !hideTableOfContents,
|
||||||
})}>
|
})}>
|
||||||
|
{latestVersionMainDocPermalink && (
|
||||||
|
<div
|
||||||
|
className="alert alert--warning margin-bottom--md"
|
||||||
|
role="alert">
|
||||||
|
{version === 'next' ? (
|
||||||
|
<div>
|
||||||
|
This is unreleased documentation for {siteTitle}{' '}
|
||||||
|
<strong>{version}</strong> version.
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div>
|
||||||
|
This is archived documentation for {siteTitle}{' '}
|
||||||
|
<strong>v{version}</strong>, which is no longer actively
|
||||||
|
maintained.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="margin-top--md">
|
||||||
|
For up-to-date documentation, see the{' '}
|
||||||
|
<strong>
|
||||||
|
<Link to={latestVersionMainDocPermalink}>
|
||||||
|
latest version
|
||||||
|
</Link>
|
||||||
|
</strong>
|
||||||
|
.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div className={styles.docItemContainer}>
|
<div className={styles.docItemContainer}>
|
||||||
<article>
|
<article>
|
||||||
{version && (
|
{version && (
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue