mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-12 00:27:21 +02:00
fix(plugin-docs,theme): refactor docs plugin routes and component tree (#7966)
This commit is contained in:
parent
c29218ea1d
commit
3b9b497d13
35 changed files with 1189 additions and 857 deletions
File diff suppressed because it is too large
Load diff
|
@ -49,7 +49,9 @@ describe('normalizeDocsPluginOptions', () => {
|
|||
sidebarPath: 'my-sidebar', // Path to sidebar configuration for showing a list of markdown pages.
|
||||
sidebarItemsGenerator: DefaultSidebarItemsGenerator,
|
||||
numberPrefixParser: DefaultNumberPrefixParser,
|
||||
docLayoutComponent: '@theme/DocPage',
|
||||
docsRootComponent: '@theme/DocsRoot',
|
||||
docVersionRootComponent: '@theme/DocVersionRoot',
|
||||
docRootComponent: '@theme/DocRoot',
|
||||
docItemComponent: '@theme/DocItem',
|
||||
docTagDocListComponent: '@theme/DocTagDocListPage',
|
||||
docTagsListComponent: '@theme/DocTagsListPage',
|
||||
|
|
|
@ -27,22 +27,18 @@ import {
|
|||
addDocNavigation,
|
||||
type DocEnv,
|
||||
} from './docs';
|
||||
import {readVersionsMetadata} from './versions';
|
||||
import {readVersionsMetadata, toFullVersion} from './versions';
|
||||
import {cliDocsVersionCommand} from './cli';
|
||||
import {VERSIONS_JSON_FILE} from './constants';
|
||||
import {toGlobalDataVersion} from './globalData';
|
||||
import {toTagDocListProp} from './props';
|
||||
import {getCategoryGeneratedIndexMetadataList} from './categoryGeneratedIndex';
|
||||
import {
|
||||
translateLoadedContent,
|
||||
getLoadedContentTranslationFiles,
|
||||
} from './translations';
|
||||
import {getVersionTags} from './tags';
|
||||
import {createVersionRoutes} from './routes';
|
||||
import {createAllRoutes} from './routes';
|
||||
import {createSidebarsUtils} from './sidebars/utils';
|
||||
|
||||
import type {
|
||||
PropTagsListPage,
|
||||
PluginOptions,
|
||||
DocMetadataBase,
|
||||
VersionMetadata,
|
||||
|
@ -55,7 +51,6 @@ import type {
|
|||
SourceToPermalink,
|
||||
DocFile,
|
||||
DocsMarkdownOption,
|
||||
VersionTag,
|
||||
FullVersion,
|
||||
} from './types';
|
||||
import type {RuleSetRule} from 'webpack';
|
||||
|
@ -209,102 +204,20 @@ export default async function pluginContentDocs(
|
|||
},
|
||||
|
||||
async contentLoaded({content, actions}) {
|
||||
const {loadedVersions} = content;
|
||||
const {
|
||||
docLayoutComponent,
|
||||
docItemComponent,
|
||||
docCategoryGeneratedIndexComponent,
|
||||
breadcrumbs,
|
||||
} = options;
|
||||
const {addRoute, createData, setGlobalData} = actions;
|
||||
const versions: FullVersion[] = loadedVersions.map((version) => {
|
||||
const sidebarsUtils = createSidebarsUtils(version.sidebars);
|
||||
return {
|
||||
...version,
|
||||
sidebarsUtils,
|
||||
categoryGeneratedIndices: getCategoryGeneratedIndexMetadataList({
|
||||
docs: version.docs,
|
||||
sidebarsUtils,
|
||||
}),
|
||||
};
|
||||
const versions: FullVersion[] = content.loadedVersions.map(toFullVersion);
|
||||
|
||||
await createAllRoutes({
|
||||
baseUrl,
|
||||
versions,
|
||||
options,
|
||||
actions,
|
||||
aliasedSource,
|
||||
});
|
||||
|
||||
async function createVersionTagsRoutes(version: FullVersion) {
|
||||
const versionTags = getVersionTags(version.docs);
|
||||
|
||||
// TODO tags should be a sub route of the version route
|
||||
async function createTagsListPage() {
|
||||
const tagsProp: PropTagsListPage['tags'] = Object.values(
|
||||
versionTags,
|
||||
).map((tagValue) => ({
|
||||
label: tagValue.label,
|
||||
permalink: tagValue.permalink,
|
||||
count: tagValue.docIds.length,
|
||||
}));
|
||||
|
||||
// Only create /tags page if there are tags.
|
||||
if (tagsProp.length > 0) {
|
||||
const tagsPropPath = await createData(
|
||||
`${docuHash(`tags-list-${version.versionName}-prop`)}.json`,
|
||||
JSON.stringify(tagsProp, null, 2),
|
||||
);
|
||||
addRoute({
|
||||
path: version.tagsPath,
|
||||
exact: true,
|
||||
component: options.docTagsListComponent,
|
||||
modules: {
|
||||
tags: aliasedSource(tagsPropPath),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// TODO tags should be a sub route of the version route
|
||||
async function createTagDocListPage(tag: VersionTag) {
|
||||
const tagProps = toTagDocListProp({
|
||||
allTagsPath: version.tagsPath,
|
||||
tag,
|
||||
docs: version.docs,
|
||||
});
|
||||
const tagPropPath = await createData(
|
||||
`${docuHash(`tag-${tag.permalink}`)}.json`,
|
||||
JSON.stringify(tagProps, null, 2),
|
||||
);
|
||||
addRoute({
|
||||
path: tag.permalink,
|
||||
component: options.docTagDocListComponent,
|
||||
exact: true,
|
||||
modules: {
|
||||
tag: aliasedSource(tagPropPath),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
await createTagsListPage();
|
||||
await Promise.all(Object.values(versionTags).map(createTagDocListPage));
|
||||
}
|
||||
|
||||
await Promise.all(
|
||||
versions.map((version) =>
|
||||
createVersionRoutes({
|
||||
version,
|
||||
docItemComponent,
|
||||
docLayoutComponent,
|
||||
docCategoryGeneratedIndexComponent,
|
||||
pluginId,
|
||||
aliasedSource,
|
||||
actions,
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
// TODO tags should be a sub route of the version route
|
||||
await Promise.all(versions.map(createVersionTagsRoutes));
|
||||
|
||||
setGlobalData({
|
||||
actions.setGlobalData({
|
||||
path: normalizeUrl([baseUrl, options.routeBasePath]),
|
||||
versions: versions.map(toGlobalDataVersion),
|
||||
breadcrumbs,
|
||||
breadcrumbs: options.breadcrumbs,
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -30,7 +30,9 @@ export const DEFAULT_OPTIONS: Omit<PluginOptions, 'id' | 'sidebarPath'> = {
|
|||
exclude: GlobExcludeDefault,
|
||||
sidebarItemsGenerator: DefaultSidebarItemsGenerator,
|
||||
numberPrefixParser: DefaultNumberPrefixParser,
|
||||
docLayoutComponent: '@theme/DocPage',
|
||||
docsRootComponent: '@theme/DocsRoot',
|
||||
docVersionRootComponent: '@theme/DocVersionRoot',
|
||||
docRootComponent: '@theme/DocRoot',
|
||||
docItemComponent: '@theme/DocItem',
|
||||
docTagDocListComponent: '@theme/DocTagDocListPage',
|
||||
docTagsListComponent: '@theme/DocTagsListPage',
|
||||
|
@ -104,7 +106,11 @@ const OptionsSchema = Joi.object<PluginOptions>({
|
|||
}),
|
||||
)
|
||||
.default(() => DEFAULT_OPTIONS.numberPrefixParser),
|
||||
docLayoutComponent: Joi.string().default(DEFAULT_OPTIONS.docLayoutComponent),
|
||||
docsRootComponent: Joi.string().default(DEFAULT_OPTIONS.docsRootComponent),
|
||||
docVersionRootComponent: Joi.string().default(
|
||||
DEFAULT_OPTIONS.docVersionRootComponent,
|
||||
),
|
||||
docRootComponent: Joi.string().default(DEFAULT_OPTIONS.docRootComponent),
|
||||
docItemComponent: Joi.string().default(DEFAULT_OPTIONS.docItemComponent),
|
||||
docTagsListComponent: Joi.string().default(
|
||||
DEFAULT_OPTIONS.docTagsListComponent,
|
||||
|
|
|
@ -198,10 +198,24 @@ declare module '@docusaurus/plugin-content-docs' {
|
|||
*/
|
||||
exclude: string[];
|
||||
/**
|
||||
* Root layout component of each doc page. Provides the version data
|
||||
* context, and is not unmounted when switching docs.
|
||||
* Parent component of all the docs plugin pages (including all versions).
|
||||
* Stays mounted when navigation between docs pages and versions.
|
||||
*/
|
||||
docLayoutComponent: string;
|
||||
docsRootComponent: string;
|
||||
/**
|
||||
* Parent component of all docs pages of an individual version:
|
||||
* - docs pages with sidebars
|
||||
* - tags pages
|
||||
* Stays mounted when navigation between pages of that specific version.
|
||||
*/
|
||||
docVersionRootComponent: string;
|
||||
/**
|
||||
* Parent component of all docs pages with sidebars:
|
||||
* - regular docs pages
|
||||
* - category generated index pages
|
||||
* Stays mounted when navigation between such pages.
|
||||
*/
|
||||
docRootComponent: string;
|
||||
/** Main doc container, with TOC, pagination, etc. */
|
||||
docItemComponent: string;
|
||||
/** Root component of the "docs containing tag X" page. */
|
||||
|
@ -610,14 +624,32 @@ declare module '@theme/DocBreadcrumbs' {
|
|||
export default function DocBreadcrumbs(): JSX.Element;
|
||||
}
|
||||
|
||||
declare module '@theme/DocPage' {
|
||||
declare module '@theme/DocsRoot' {
|
||||
import type {RouteConfigComponentProps} from 'react-router-config';
|
||||
import type {Required} from 'utility-types';
|
||||
|
||||
export interface Props extends Required<RouteConfigComponentProps, 'route'> {}
|
||||
|
||||
export default function DocsRoot(props: Props): JSX.Element;
|
||||
}
|
||||
|
||||
declare module '@theme/DocVersionRoot' {
|
||||
import type {PropVersionMetadata} from '@docusaurus/plugin-content-docs';
|
||||
import type {RouteConfigComponentProps} from 'react-router-config';
|
||||
import type {Required} from 'utility-types';
|
||||
|
||||
export interface Props extends Required<RouteConfigComponentProps, 'route'> {
|
||||
readonly versionMetadata: PropVersionMetadata;
|
||||
readonly version: PropVersionMetadata;
|
||||
}
|
||||
|
||||
export default function DocPage(props: Props): JSX.Element;
|
||||
export default function DocVersionRoot(props: Props): JSX.Element;
|
||||
}
|
||||
|
||||
declare module '@theme/DocRoot' {
|
||||
import type {RouteConfigComponentProps} from 'react-router-config';
|
||||
import type {Required} from 'utility-types';
|
||||
|
||||
export interface Props extends Required<RouteConfigComponentProps, 'route'> {}
|
||||
|
||||
export default function DocRoot(props: Props): JSX.Element;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import _ from 'lodash';
|
||||
import {createDocsByIdIndex} from './docs';
|
||||
import type {VersionTag} from './types';
|
||||
import type {VersionTag, VersionTags} from './types';
|
||||
import type {
|
||||
SidebarItemDoc,
|
||||
SidebarItem,
|
||||
|
@ -21,6 +21,7 @@ import type {
|
|||
PropSidebarItemCategory,
|
||||
PropTagDocList,
|
||||
PropTagDocListDoc,
|
||||
PropTagsListPage,
|
||||
PropSidebarItemLink,
|
||||
PropVersionDocs,
|
||||
DocMetadata,
|
||||
|
@ -181,3 +182,13 @@ export function toTagDocListProp({
|
|||
items: toDocListProp(),
|
||||
};
|
||||
}
|
||||
|
||||
export function toTagsListTagsProp(
|
||||
versionTags: VersionTags,
|
||||
): PropTagsListPage['tags'] {
|
||||
return Object.values(versionTags).map((tagValue) => ({
|
||||
label: tagValue.label,
|
||||
permalink: tagValue.permalink,
|
||||
count: tagValue.docIds.length,
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -5,30 +5,32 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import _ from 'lodash';
|
||||
import logger from '@docusaurus/logger';
|
||||
import {docuHash, createSlugger} from '@docusaurus/utils';
|
||||
import {toVersionMetadataProp} from './props';
|
||||
import {docuHash, createSlugger, normalizeUrl} from '@docusaurus/utils';
|
||||
import {
|
||||
toTagDocListProp,
|
||||
toTagsListTagsProp,
|
||||
toVersionMetadataProp,
|
||||
} from './props';
|
||||
import {getVersionTags} from './tags';
|
||||
import type {PluginContentLoadedActions, RouteConfig} from '@docusaurus/types';
|
||||
import type {FullVersion} from './types';
|
||||
import type {FullVersion, VersionTag} from './types';
|
||||
import type {
|
||||
CategoryGeneratedIndexMetadata,
|
||||
DocMetadata,
|
||||
PluginOptions,
|
||||
PropTagsListPage,
|
||||
} from '@docusaurus/plugin-content-docs';
|
||||
|
||||
export async function createCategoryGeneratedIndexRoutes({
|
||||
async function buildVersionCategoryGeneratedIndexRoutes({
|
||||
version,
|
||||
actions,
|
||||
docCategoryGeneratedIndexComponent,
|
||||
options,
|
||||
aliasedSource,
|
||||
}: {
|
||||
version: FullVersion;
|
||||
actions: PluginContentLoadedActions;
|
||||
docCategoryGeneratedIndexComponent: string;
|
||||
aliasedSource: (str: string) => string;
|
||||
}): Promise<RouteConfig[]> {
|
||||
}: BuildVersionRoutesParam): Promise<RouteConfig[]> {
|
||||
const slugs = createSlugger();
|
||||
|
||||
async function createCategoryGeneratedIndexRoute(
|
||||
async function buildCategoryGeneratedIndexRoute(
|
||||
categoryGeneratedIndex: CategoryGeneratedIndexMetadata,
|
||||
): Promise<RouteConfig> {
|
||||
const {sidebar, ...prop} = categoryGeneratedIndex;
|
||||
|
@ -44,7 +46,7 @@ export async function createCategoryGeneratedIndexRoutes({
|
|||
|
||||
return {
|
||||
path: categoryGeneratedIndex.permalink,
|
||||
component: docCategoryGeneratedIndexComponent,
|
||||
component: options.docCategoryGeneratedIndexComponent,
|
||||
exact: true,
|
||||
modules: {
|
||||
categoryGeneratedIndex: aliasedSource(propData),
|
||||
|
@ -56,21 +58,17 @@ export async function createCategoryGeneratedIndexRoutes({
|
|||
}
|
||||
|
||||
return Promise.all(
|
||||
version.categoryGeneratedIndices.map(createCategoryGeneratedIndexRoute),
|
||||
version.categoryGeneratedIndices.map(buildCategoryGeneratedIndexRoute),
|
||||
);
|
||||
}
|
||||
|
||||
export async function createDocRoutes({
|
||||
docs,
|
||||
async function buildVersionDocRoutes({
|
||||
version,
|
||||
actions,
|
||||
docItemComponent,
|
||||
}: {
|
||||
docs: DocMetadata[];
|
||||
actions: PluginContentLoadedActions;
|
||||
docItemComponent: string;
|
||||
}): Promise<RouteConfig[]> {
|
||||
options,
|
||||
}: BuildVersionRoutesParam): Promise<RouteConfig[]> {
|
||||
return Promise.all(
|
||||
docs.map(async (metadataItem) => {
|
||||
version.docs.map(async (metadataItem) => {
|
||||
await actions.createData(
|
||||
// Note that this created data path must be in sync with
|
||||
// metadataPath provided to mdx-loader.
|
||||
|
@ -80,12 +78,12 @@ export async function createDocRoutes({
|
|||
|
||||
const docRoute: RouteConfig = {
|
||||
path: metadataItem.permalink,
|
||||
component: docItemComponent,
|
||||
component: options.docItemComponent,
|
||||
exact: true,
|
||||
modules: {
|
||||
content: metadataItem.source,
|
||||
},
|
||||
// Because the parent (DocPage) comp need to access it easily
|
||||
// Because the parent (DocRoot) comp need to access it easily
|
||||
// This permits to render the sidebar once without unmount/remount when
|
||||
// navigating (and preserve sidebar state)
|
||||
...(metadataItem.sidebar && {
|
||||
|
@ -98,62 +96,160 @@ export async function createDocRoutes({
|
|||
);
|
||||
}
|
||||
|
||||
export async function createVersionRoutes({
|
||||
version,
|
||||
actions,
|
||||
docItemComponent,
|
||||
docLayoutComponent,
|
||||
docCategoryGeneratedIndexComponent,
|
||||
pluginId,
|
||||
aliasedSource,
|
||||
}: {
|
||||
version: FullVersion;
|
||||
actions: PluginContentLoadedActions;
|
||||
docLayoutComponent: string;
|
||||
docItemComponent: string;
|
||||
docCategoryGeneratedIndexComponent: string;
|
||||
pluginId: string;
|
||||
aliasedSource: (str: string) => string;
|
||||
}): Promise<void> {
|
||||
async function doCreateVersionRoutes(): Promise<void> {
|
||||
const versionMetadata = toVersionMetadataProp(pluginId, version);
|
||||
const versionMetadataPropPath = await actions.createData(
|
||||
`${docuHash(`version-${version.versionName}-metadata-prop`)}.json`,
|
||||
JSON.stringify(versionMetadata, null, 2),
|
||||
);
|
||||
async function buildVersionSidebarRoute(param: BuildVersionRoutesParam) {
|
||||
const [docRoutes, categoryGeneratedIndexRoutes] = await Promise.all([
|
||||
buildVersionDocRoutes(param),
|
||||
buildVersionCategoryGeneratedIndexRoutes(param),
|
||||
]);
|
||||
const subRoutes = [...docRoutes, ...categoryGeneratedIndexRoutes];
|
||||
return {
|
||||
path: param.version.path,
|
||||
exact: false,
|
||||
component: param.options.docRootComponent,
|
||||
routes: subRoutes,
|
||||
};
|
||||
}
|
||||
|
||||
async function createVersionSubRoutes() {
|
||||
const [docRoutes, sidebarsRoutes] = await Promise.all([
|
||||
createDocRoutes({docs: version.docs, actions, docItemComponent}),
|
||||
createCategoryGeneratedIndexRoutes({
|
||||
version,
|
||||
actions,
|
||||
docCategoryGeneratedIndexComponent,
|
||||
aliasedSource,
|
||||
}),
|
||||
]);
|
||||
async function buildVersionTagsRoutes(
|
||||
param: BuildVersionRoutesParam,
|
||||
): Promise<RouteConfig[]> {
|
||||
const {version, options, actions, aliasedSource} = param;
|
||||
const versionTags = getVersionTags(version.docs);
|
||||
|
||||
const routes = [...docRoutes, ...sidebarsRoutes];
|
||||
return routes.sort((a, b) => a.path.localeCompare(b.path));
|
||||
async function buildTagsListRoute(): Promise<RouteConfig | null> {
|
||||
// Don't create a tags list page if there's no tag
|
||||
if (Object.keys(versionTags).length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
actions.addRoute({
|
||||
path: version.path,
|
||||
// Allow matching /docs/* since this is the wrapping route
|
||||
exact: false,
|
||||
component: docLayoutComponent,
|
||||
routes: await createVersionSubRoutes(),
|
||||
const tagsProp: PropTagsListPage['tags'] = toTagsListTagsProp(versionTags);
|
||||
const tagsPropPath = await actions.createData(
|
||||
`${docuHash(`tags-list-${version.versionName}-prop`)}.json`,
|
||||
JSON.stringify(tagsProp, null, 2),
|
||||
);
|
||||
return {
|
||||
path: version.tagsPath,
|
||||
exact: true,
|
||||
component: options.docTagsListComponent,
|
||||
modules: {
|
||||
versionMetadata: aliasedSource(versionMetadataPropPath),
|
||||
tags: aliasedSource(tagsPropPath),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async function buildTagDocListRoute(tag: VersionTag): Promise<RouteConfig> {
|
||||
const tagProps = toTagDocListProp({
|
||||
allTagsPath: version.tagsPath,
|
||||
tag,
|
||||
docs: version.docs,
|
||||
});
|
||||
const tagPropPath = await actions.createData(
|
||||
`${docuHash(`tag-${tag.permalink}`)}.json`,
|
||||
JSON.stringify(tagProps, null, 2),
|
||||
);
|
||||
return {
|
||||
path: tag.permalink,
|
||||
component: options.docTagDocListComponent,
|
||||
exact: true,
|
||||
modules: {
|
||||
tag: aliasedSource(tagPropPath),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const [tagsListRoute, allTagsDocListRoutes] = await Promise.all([
|
||||
buildTagsListRoute(),
|
||||
Promise.all(Object.values(versionTags).map(buildTagDocListRoute)),
|
||||
]);
|
||||
|
||||
return _.compact([tagsListRoute, ...allTagsDocListRoutes]);
|
||||
}
|
||||
|
||||
type BuildVersionRoutesParam = Omit<BuildAllRoutesParam, 'versions'> & {
|
||||
version: FullVersion;
|
||||
};
|
||||
|
||||
async function buildVersionRoutes(
|
||||
param: BuildVersionRoutesParam,
|
||||
): Promise<RouteConfig> {
|
||||
const {version, actions, options, aliasedSource} = param;
|
||||
|
||||
async function buildVersionSubRoutes() {
|
||||
const [sidebarRoute, tagsRoutes] = await Promise.all([
|
||||
buildVersionSidebarRoute(param),
|
||||
buildVersionTagsRoutes(param),
|
||||
]);
|
||||
|
||||
return [sidebarRoute, ...tagsRoutes];
|
||||
}
|
||||
|
||||
async function doBuildVersionRoutes(): Promise<RouteConfig> {
|
||||
const versionProp = toVersionMetadataProp(options.id, version);
|
||||
const versionPropPath = await actions.createData(
|
||||
`${docuHash(`version-${version.versionName}-metadata-prop`)}.json`,
|
||||
JSON.stringify(versionProp, null, 2),
|
||||
);
|
||||
const subRoutes = await buildVersionSubRoutes();
|
||||
return {
|
||||
path: version.path,
|
||||
exact: false,
|
||||
component: options.docVersionRootComponent,
|
||||
routes: subRoutes,
|
||||
modules: {
|
||||
version: aliasedSource(versionPropPath),
|
||||
},
|
||||
priority: version.routePriority,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
return await doCreateVersionRoutes();
|
||||
return await doBuildVersionRoutes();
|
||||
} catch (err) {
|
||||
logger.error`Can't create version routes for version name=${version.versionName}`;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
type BuildAllRoutesParam = Omit<CreateAllRoutesParam, 'actions'> & {
|
||||
actions: Omit<PluginContentLoadedActions, 'addRoute' | 'setGlobalData'>;
|
||||
};
|
||||
|
||||
// TODO we want this buildAllRoutes function to be easily testable
|
||||
// Ideally, we should avoid side effects here (ie not injecting actions)
|
||||
export async function buildAllRoutes(
|
||||
param: BuildAllRoutesParam,
|
||||
): Promise<RouteConfig[]> {
|
||||
const subRoutes = await Promise.all(
|
||||
param.versions.map((version) =>
|
||||
buildVersionRoutes({
|
||||
...param,
|
||||
version,
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
// all docs routes are wrapped under a single parent route, this ensures
|
||||
// the theme layout never unmounts/remounts when navigating between versions
|
||||
return [
|
||||
{
|
||||
path: normalizeUrl([param.baseUrl, param.options.routeBasePath]),
|
||||
exact: false,
|
||||
component: param.options.docsRootComponent,
|
||||
routes: subRoutes,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
type CreateAllRoutesParam = {
|
||||
baseUrl: string;
|
||||
versions: FullVersion[];
|
||||
options: PluginOptions;
|
||||
actions: PluginContentLoadedActions;
|
||||
aliasedSource: (str: string) => string;
|
||||
};
|
||||
|
||||
export async function createAllRoutes(
|
||||
param: CreateAllRoutesParam,
|
||||
): Promise<void> {
|
||||
const routes = await buildAllRoutes(param);
|
||||
routes.forEach(param.actions.addRoute);
|
||||
}
|
||||
|
|
|
@ -14,12 +14,16 @@ import {
|
|||
getVersionMetadataPaths,
|
||||
readVersionNames,
|
||||
} from './files';
|
||||
import {createSidebarsUtils} from '../sidebars/utils';
|
||||
import {getCategoryGeneratedIndexMetadataList} from '../categoryGeneratedIndex';
|
||||
import type {FullVersion} from '../types';
|
||||
import type {LoadContext} from '@docusaurus/types';
|
||||
import type {
|
||||
LoadedVersion,
|
||||
PluginOptions,
|
||||
VersionBanner,
|
||||
VersionMetadata,
|
||||
} from '@docusaurus/plugin-content-docs';
|
||||
import type {LoadContext} from '@docusaurus/types';
|
||||
|
||||
export type VersionContext = {
|
||||
/** The version name to get banner of. */
|
||||
|
@ -252,3 +256,15 @@ export async function readVersionsMetadata({
|
|||
);
|
||||
return versionsMetadata;
|
||||
}
|
||||
|
||||
export function toFullVersion(version: LoadedVersion): FullVersion {
|
||||
const sidebarsUtils = createSidebarsUtils(version.sidebars);
|
||||
return {
|
||||
...version,
|
||||
sidebarsUtils,
|
||||
categoryGeneratedIndices: getCategoryGeneratedIndexMetadataList({
|
||||
docs: version.docs,
|
||||
sidebarsUtils,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue