diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap index 2a675b5ecfe5..e0ace0c024b2 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap @@ -1083,38 +1083,6 @@ exports[`simple website content: global data 1`] = ` exports[`simple website content: route config 1`] = ` [ - { - "component": "@theme/DocTagsListPage", - "exact": true, - "modules": { - "tags": "~docs/tags-list-current-prop-15a.json", - }, - "path": "/docs/tags", - }, - { - "component": "@theme/DocTagDocListPage", - "exact": true, - "modules": { - "tag": "~docs/tag-docs-tags-tag-1-b3f.json", - }, - "path": "/docs/tags/tag-1", - }, - { - "component": "@theme/DocTagDocListPage", - "exact": true, - "modules": { - "tag": "~docs/tag-docs-tags-tag-3-ab5.json", - }, - "path": "/docs/tags/tag-3", - }, - { - "component": "@theme/DocTagDocListPage", - "exact": true, - "modules": { - "tag": "~docs/tag-docs-tags-tag-2-custom-permalink-825.json", - }, - "path": "/docs/tags/tag2-custom-permalink", - }, { "component": "@theme/DocPage", "exact": false, @@ -1253,6 +1221,38 @@ exports[`simple website content: route config 1`] = ` }, "path": "/docs/slugs/relativeSlug", }, + { + "component": "@theme/DocTagsListPage", + "exact": true, + "modules": { + "tags": "~docs/tags-list-current-prop-15a.json", + }, + "path": "/docs/tags", + }, + { + "component": "@theme/DocTagDocListPage", + "exact": true, + "modules": { + "tag": "~docs/tag-docs-tags-tag-1-b3f.json", + }, + "path": "/docs/tags/tag-1", + }, + { + "component": "@theme/DocTagDocListPage", + "exact": true, + "modules": { + "tag": "~docs/tag-docs-tags-tag-3-ab5.json", + }, + "path": "/docs/tags/tag-3", + }, + { + "component": "@theme/DocTagDocListPage", + "exact": true, + "modules": { + "tag": "~docs/tag-docs-tags-tag-2-custom-permalink-825.json", + }, + "path": "/docs/tags/tag2-custom-permalink", + }, { "component": "@theme/DocItem", "exact": true, @@ -3681,38 +3681,6 @@ exports[`versioned website content: global data 1`] = ` exports[`versioned website content: route config 1`] = ` [ - { - "component": "@theme/DocTagsListPage", - "exact": true, - "modules": { - "tags": "~docs/tags-list-current-prop-15a.json", - }, - "path": "/docs/next/tags", - }, - { - "component": "@theme/DocTagDocListPage", - "exact": true, - "modules": { - "tag": "~docs/tag-docs-next-tags-bar-tag-1-a8f.json", - }, - "path": "/docs/next/tags/bar-tag-1", - }, - { - "component": "@theme/DocTagDocListPage", - "exact": true, - "modules": { - "tag": "~docs/tag-docs-next-tags-bar-tag-2-216.json", - }, - "path": "/docs/next/tags/bar-tag-2", - }, - { - "component": "@theme/DocTagDocListPage", - "exact": true, - "modules": { - "tag": "~docs/tag-docs-next-tags-bar-tag-3-permalink-94a.json", - }, - "path": "/docs/next/tags/barTag-3-permalink", - }, { "component": "@theme/DocPage", "exact": false, @@ -3802,6 +3770,38 @@ exports[`versioned website content: route config 1`] = ` }, "path": "/docs/next/slugs/relativeSlug", }, + { + "component": "@theme/DocTagsListPage", + "exact": true, + "modules": { + "tags": "~docs/tags-list-current-prop-15a.json", + }, + "path": "/docs/next/tags", + }, + { + "component": "@theme/DocTagDocListPage", + "exact": true, + "modules": { + "tag": "~docs/tag-docs-next-tags-bar-tag-1-a8f.json", + }, + "path": "/docs/next/tags/bar-tag-1", + }, + { + "component": "@theme/DocTagDocListPage", + "exact": true, + "modules": { + "tag": "~docs/tag-docs-next-tags-bar-tag-2-216.json", + }, + "path": "/docs/next/tags/bar-tag-2", + }, + { + "component": "@theme/DocTagDocListPage", + "exact": true, + "modules": { + "tag": "~docs/tag-docs-next-tags-bar-tag-3-permalink-94a.json", + }, + "path": "/docs/next/tags/barTag-3-permalink", + }, { "component": "@theme/DocItem", "exact": true, diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index 988927677539..a3405608fbcf 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -35,22 +35,18 @@ import type { LoadedVersion, DocFile, DocsMarkdownOption, - VersionTag, } from './types'; import type {RuleSetRule} from 'webpack'; import {cliDocsVersionCommand} from './cli'; import {VERSIONS_JSON_FILE} from './constants'; import {toGlobalDataVersion} from './globalData'; -import {toTagDocListProp} from './props'; import { translateLoadedContent, getLoadedContentTranslationFiles, } from './translations'; import logger from '@docusaurus/logger'; -import {getVersionTags} from './tags'; import {createVersionRoutes} from './routes'; import type { - PropTagsListPage, PluginOptions, DocMetadataBase, VersionMetadata, @@ -213,64 +209,11 @@ export default async function pluginContentDocs( docLayoutComponent, docItemComponent, docCategoryGeneratedIndexComponent, + docTagsListComponent, + docTagDocListComponent, breadcrumbs, } = options; - const {addRoute, createData, setGlobalData} = actions; - - async function createVersionTagsRoutes(version: LoadedVersion) { - 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)); - } + const {setGlobalData} = actions; await Promise.all( loadedVersions.map((loadedVersion) => @@ -279,6 +222,8 @@ export default async function pluginContentDocs( docItemComponent, docLayoutComponent, docCategoryGeneratedIndexComponent, + docTagsListComponent, + docTagDocListComponent, pluginId, aliasedSource, actions, @@ -286,9 +231,6 @@ export default async function pluginContentDocs( ), ); - // TODO tags should be a sub route of the version route - await Promise.all(loadedVersions.map(createVersionTagsRoutes)); - setGlobalData({ path: normalizeUrl([baseUrl, options.routeBasePath]), versions: loadedVersions.map(toGlobalDataVersion), diff --git a/packages/docusaurus-plugin-content-docs/src/routes.ts b/packages/docusaurus-plugin-content-docs/src/routes.ts index 3ef6e60ba146..f6dba1f9776c 100644 --- a/packages/docusaurus-plugin-content-docs/src/routes.ts +++ b/packages/docusaurus-plugin-content-docs/src/routes.ts @@ -7,15 +7,16 @@ import type {PluginContentLoadedActions, RouteConfig} from '@docusaurus/types'; import {docuHash, createSlugger} from '@docusaurus/utils'; -import type {LoadedVersion} from './types'; +import type {LoadedVersion, VersionTag} from './types'; import type { CategoryGeneratedIndexMetadata, - DocMetadata, + PropTagsListPage, } from '@docusaurus/plugin-content-docs'; -import {toVersionMetadataProp} from './props'; +import {toVersionMetadataProp, toTagDocListProp} from './props'; +import {getVersionTags} from './tags'; import logger from '@docusaurus/logger'; -export async function createCategoryGeneratedIndexRoutes({ +async function createCategoryGeneratedIndexRoutes({ version, actions, docCategoryGeneratedIndexComponent, @@ -60,17 +61,17 @@ export async function createCategoryGeneratedIndexRoutes({ ); } -export async function createDocRoutes({ - docs, +async function createDocRoutes({ + version, actions, docItemComponent, }: { - docs: DocMetadata[]; + version: LoadedVersion; actions: PluginContentLoadedActions; docItemComponent: string; }): Promise { 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. @@ -98,12 +99,78 @@ export async function createDocRoutes({ ); } +async function createTagsRoutes({ + version, + actions, + docTagsListComponent, + docTagDocListComponent, + aliasedSource, +}: { + version: LoadedVersion; + actions: PluginContentLoadedActions; + docTagsListComponent: string; + docTagDocListComponent: string; + aliasedSource: (str: string) => string; +}): Promise { + const tags = Object.values(getVersionTags(version.docs)); + + async function createTagsListPage(): Promise { + const tagsProp: PropTagsListPage['tags'] = tags.map((tag) => ({ + label: tag.label, + permalink: tag.permalink, + count: tag.docIds.length, + })); + + const tagsPropPath = await actions.createData( + `${docuHash(`tags-list-${version.versionName}-prop`)}.json`, + JSON.stringify(tagsProp, null, 2), + ); + return { + path: version.tagsPath, + exact: true, + component: docTagsListComponent, + modules: { + tags: aliasedSource(tagsPropPath), + }, + }; + } + + async function createTagDocListPage(tag: VersionTag): Promise { + 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: docTagDocListComponent, + exact: true, + modules: { + tag: aliasedSource(tagPropPath), + }, + }; + } + const tagsRoutes = tags.map(createTagDocListPage); + // Only create /tags page if there are tags. + if (tags.length > 0) { + tagsRoutes.push(createTagsListPage()); + } + + return Promise.all(tagsRoutes); +} + export async function createVersionRoutes({ loadedVersion, actions, docItemComponent, docLayoutComponent, docCategoryGeneratedIndexComponent, + docTagsListComponent, + docTagDocListComponent, pluginId, aliasedSource, }: { @@ -112,6 +179,8 @@ export async function createVersionRoutes({ docLayoutComponent: string; docItemComponent: string; docCategoryGeneratedIndexComponent: string; + docTagsListComponent: string; + docTagDocListComponent: string; pluginId: string; aliasedSource: (str: string) => string; }): Promise { @@ -123,17 +192,24 @@ export async function createVersionRoutes({ ); async function createVersionSubRoutes() { - const [docRoutes, sidebarsRoutes] = await Promise.all([ - createDocRoutes({docs: version.docs, actions, docItemComponent}), + const [docRoutes, sidebarsRoutes, tagsRoutes] = await Promise.all([ + createDocRoutes({version, actions, docItemComponent}), createCategoryGeneratedIndexRoutes({ version, actions, docCategoryGeneratedIndexComponent, aliasedSource, }), + createTagsRoutes({ + version, + actions, + docTagsListComponent, + docTagDocListComponent, + aliasedSource, + }), ]); - const routes = [...docRoutes, ...sidebarsRoutes]; + const routes = [...docRoutes, ...sidebarsRoutes, ...tagsRoutes]; return routes.sort((a, b) => a.path.localeCompare(b.path)); }