mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-19 03:02:30 +02:00
feat(content-docs): expose isCategoryIndex matcher to customize conventions (#6451)
Co-authored-by: sebastienlorber <lorber.sebastien@gmail.com>
This commit is contained in:
parent
76a8d5f38a
commit
24a895fbc5
16 changed files with 408 additions and 93 deletions
|
@ -12,6 +12,7 @@ import {
|
|||
import type {Sidebar, SidebarItemsGenerator} from '../types';
|
||||
import fs from 'fs-extra';
|
||||
import {DefaultNumberPrefixParser} from '../../numberPrefix';
|
||||
import {isCategoryIndex} from '../../docs';
|
||||
|
||||
describe('DefaultSidebarItemsGenerator', () => {
|
||||
function testDefaultSidebarItemsGenerator(
|
||||
|
@ -19,6 +20,7 @@ describe('DefaultSidebarItemsGenerator', () => {
|
|||
) {
|
||||
return DefaultSidebarItemsGenerator({
|
||||
numberPrefixParser: DefaultNumberPrefixParser,
|
||||
isCategoryIndex,
|
||||
item: {
|
||||
type: 'autogenerated',
|
||||
dirName: '.',
|
||||
|
@ -146,6 +148,7 @@ describe('DefaultSidebarItemsGenerator', () => {
|
|||
|
||||
const sidebarSlice = await DefaultSidebarItemsGenerator({
|
||||
numberPrefixParser: DefaultNumberPrefixParser,
|
||||
isCategoryIndex,
|
||||
item: {
|
||||
type: 'autogenerated',
|
||||
dirName: '.',
|
||||
|
@ -157,48 +160,48 @@ describe('DefaultSidebarItemsGenerator', () => {
|
|||
docs: [
|
||||
{
|
||||
id: 'intro',
|
||||
source: 'intro.md',
|
||||
source: '@site/docs/intro.md',
|
||||
sourceDirName: '.',
|
||||
sidebarPosition: 1,
|
||||
frontMatter: {},
|
||||
},
|
||||
{
|
||||
id: 'tutorials-index',
|
||||
source: 'index.md',
|
||||
source: '@site/docs/01-Tutorials/index.md',
|
||||
sourceDirName: '01-Tutorials',
|
||||
sidebarPosition: 2,
|
||||
frontMatter: {},
|
||||
},
|
||||
{
|
||||
id: 'tutorial2',
|
||||
source: 'tutorial2.md',
|
||||
source: '@site/docs/01-Tutorials/tutorial2.md',
|
||||
sourceDirName: '01-Tutorials',
|
||||
sidebarPosition: 2,
|
||||
frontMatter: {},
|
||||
},
|
||||
{
|
||||
id: 'tutorial1',
|
||||
source: 'tutorial1.md',
|
||||
source: '@site/docs/01-Tutorials/tutorial1.md',
|
||||
sourceDirName: '01-Tutorials',
|
||||
sidebarPosition: 1,
|
||||
frontMatter: {},
|
||||
},
|
||||
{
|
||||
id: 'guides-index',
|
||||
source: '02-Guides.md', // TODO should we allow to just use "Guides.md" to have an index?
|
||||
source: '@site/docs/02-Guides/02-Guides.md', // TODO should we allow to just use "Guides.md" to have an index?
|
||||
sourceDirName: '02-Guides',
|
||||
frontMatter: {},
|
||||
},
|
||||
{
|
||||
id: 'guide2',
|
||||
source: 'guide2.md',
|
||||
source: '@site/docs/02-Guides/guide2.md',
|
||||
sourceDirName: '02-Guides',
|
||||
sidebarPosition: 2,
|
||||
frontMatter: {},
|
||||
},
|
||||
{
|
||||
id: 'guide1',
|
||||
source: 'guide1.md',
|
||||
source: '@site/docs/02-Guides/guide1.md',
|
||||
sourceDirName: '02-Guides',
|
||||
sidebarPosition: 1,
|
||||
frontMatter: {
|
||||
|
@ -207,14 +210,14 @@ describe('DefaultSidebarItemsGenerator', () => {
|
|||
},
|
||||
{
|
||||
id: 'nested-guide',
|
||||
source: 'nested-guide.md',
|
||||
source: '@site/docs/02-Guides/01-SubGuides/nested-guide.md',
|
||||
sourceDirName: '02-Guides/01-SubGuides',
|
||||
sidebarPosition: undefined,
|
||||
frontMatter: {},
|
||||
},
|
||||
{
|
||||
id: 'end',
|
||||
source: 'end.md',
|
||||
source: '@site/docs/end.md',
|
||||
sourceDirName: '.',
|
||||
sidebarPosition: 3,
|
||||
frontMatter: {},
|
||||
|
@ -296,6 +299,7 @@ describe('DefaultSidebarItemsGenerator', () => {
|
|||
|
||||
const sidebarSlice = await DefaultSidebarItemsGenerator({
|
||||
numberPrefixParser: DefaultNumberPrefixParser,
|
||||
isCategoryIndex,
|
||||
item: {
|
||||
type: 'autogenerated',
|
||||
dirName: 'subfolder/subsubfolder',
|
||||
|
@ -427,19 +431,19 @@ describe('DefaultSidebarItemsGenerator', () => {
|
|||
docs: [
|
||||
{
|
||||
id: 'parent/doc1',
|
||||
source: 'index.md',
|
||||
source: '@site/docs/Category/index.md',
|
||||
sourceDirName: 'Category',
|
||||
frontMatter: {},
|
||||
},
|
||||
{
|
||||
id: 'parent/doc2',
|
||||
source: 'index.md',
|
||||
source: '@site/docs/Category/index.md',
|
||||
sourceDirName: 'Category',
|
||||
frontMatter: {},
|
||||
},
|
||||
{
|
||||
id: 'parent/doc3',
|
||||
source: 'doc3.md',
|
||||
source: '@site/docs/Category/doc3.md',
|
||||
sourceDirName: 'Category',
|
||||
frontMatter: {},
|
||||
},
|
||||
|
@ -473,4 +477,116 @@ describe('DefaultSidebarItemsGenerator', () => {
|
|||
},
|
||||
] as Sidebar);
|
||||
});
|
||||
|
||||
test('respects custom isCategoryIndex', async () => {
|
||||
const sidebarSlice = await DefaultSidebarItemsGenerator({
|
||||
numberPrefixParser: DefaultNumberPrefixParser,
|
||||
isCategoryIndex({fileName, directories}) {
|
||||
return (
|
||||
fileName.replace(
|
||||
`${DefaultNumberPrefixParser(
|
||||
directories[0],
|
||||
).filename.toLowerCase()}-`,
|
||||
'',
|
||||
) === 'index'
|
||||
);
|
||||
},
|
||||
item: {
|
||||
type: 'autogenerated',
|
||||
dirName: '.',
|
||||
},
|
||||
version: {
|
||||
versionName: 'current',
|
||||
contentPath: '',
|
||||
},
|
||||
docs: [
|
||||
{
|
||||
id: 'intro',
|
||||
source: '@site/docs/intro.md',
|
||||
sourceDirName: '.',
|
||||
sidebarPosition: 1,
|
||||
frontMatter: {},
|
||||
},
|
||||
{
|
||||
id: 'tutorials-index',
|
||||
source: '@site/docs/01-Tutorials/tutorials-index.md',
|
||||
sourceDirName: '01-Tutorials',
|
||||
sidebarPosition: 2,
|
||||
frontMatter: {},
|
||||
},
|
||||
{
|
||||
id: 'tutorial2',
|
||||
source: '@site/docs/01-Tutorials/tutorial2.md',
|
||||
sourceDirName: '01-Tutorials',
|
||||
sidebarPosition: 2,
|
||||
frontMatter: {},
|
||||
},
|
||||
{
|
||||
id: 'tutorial1',
|
||||
source: '@site/docs/01-Tutorials/tutorial1.md',
|
||||
sourceDirName: '01-Tutorials',
|
||||
sidebarPosition: 1,
|
||||
frontMatter: {},
|
||||
},
|
||||
{
|
||||
id: 'not-guides-index',
|
||||
source: '@site/docs/02-Guides/README.md',
|
||||
sourceDirName: '02-Guides',
|
||||
frontMatter: {},
|
||||
},
|
||||
{
|
||||
id: 'guide2',
|
||||
source: '@site/docs/02-Guides/guide2.md',
|
||||
sourceDirName: '02-Guides',
|
||||
sidebarPosition: 2,
|
||||
frontMatter: {},
|
||||
},
|
||||
{
|
||||
id: 'guide1',
|
||||
source: '@site/docs/02-Guides/guide1.md',
|
||||
sourceDirName: '02-Guides',
|
||||
sidebarPosition: 1,
|
||||
frontMatter: {
|
||||
sidebar_class_name: 'foo',
|
||||
},
|
||||
},
|
||||
],
|
||||
options: {
|
||||
sidebarCollapsed: true,
|
||||
sidebarCollapsible: true,
|
||||
},
|
||||
});
|
||||
|
||||
expect(sidebarSlice).toEqual([
|
||||
{type: 'doc', id: 'intro'},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Tutorials',
|
||||
collapsed: true,
|
||||
collapsible: true,
|
||||
link: {
|
||||
type: 'doc',
|
||||
id: 'tutorials-index',
|
||||
},
|
||||
items: [
|
||||
{type: 'doc', id: 'tutorial1'},
|
||||
{type: 'doc', id: 'tutorial2'},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Guides',
|
||||
collapsed: true,
|
||||
collapsible: true,
|
||||
items: [
|
||||
{type: 'doc', id: 'guide1', className: 'foo'},
|
||||
{type: 'doc', id: 'guide2'},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'not-guides-index',
|
||||
},
|
||||
],
|
||||
},
|
||||
] as Sidebar);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,6 +16,7 @@ import {DefaultSidebarItemsGenerator} from '../generator';
|
|||
import {createSlugger} from '@docusaurus/utils';
|
||||
import type {VersionMetadata} from '../../types';
|
||||
import {DefaultNumberPrefixParser} from '../../numberPrefix';
|
||||
import {isCategoryIndex} from '../../docs';
|
||||
|
||||
describe('processSidebars', () => {
|
||||
function createStaticSidebarItemGenerator(
|
||||
|
@ -137,6 +138,7 @@ describe('processSidebars', () => {
|
|||
versionName: version.versionName,
|
||||
},
|
||||
numberPrefixParser: DefaultNumberPrefixParser,
|
||||
isCategoryIndex,
|
||||
options: params.sidebarOptions,
|
||||
});
|
||||
expect(StaticSidebarItemsGenerator).toHaveBeenCalledWith({
|
||||
|
@ -147,6 +149,7 @@ describe('processSidebars', () => {
|
|||
versionName: version.versionName,
|
||||
},
|
||||
numberPrefixParser: DefaultNumberPrefixParser,
|
||||
isCategoryIndex,
|
||||
options: params.sidebarOptions,
|
||||
});
|
||||
expect(StaticSidebarItemsGenerator).toHaveBeenCalledWith({
|
||||
|
@ -157,6 +160,7 @@ describe('processSidebars', () => {
|
|||
versionName: version.versionName,
|
||||
},
|
||||
numberPrefixParser: DefaultNumberPrefixParser,
|
||||
isCategoryIndex,
|
||||
options: params.sidebarOptions,
|
||||
});
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ import path from 'path';
|
|||
import fs from 'fs-extra';
|
||||
import Yaml from 'js-yaml';
|
||||
import {validateCategoryMetadataFile} from './validation';
|
||||
import {createDocsByIdIndex, isConventionalDocIndex} from '../docs';
|
||||
import {createDocsByIdIndex, toCategoryIndexMatcherParam} from '../docs';
|
||||
|
||||
const BreadcrumbSeparator = '/';
|
||||
// To avoid possible name clashes with a folder of the same name as the ID
|
||||
|
@ -94,6 +94,7 @@ async function readCategoryMetadataFile(
|
|||
// Comment for this feature: https://github.com/facebook/docusaurus/issues/3464#issuecomment-818670449
|
||||
export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
|
||||
numberPrefixParser,
|
||||
isCategoryIndex,
|
||||
docs: allDocs,
|
||||
options,
|
||||
item: {dirName: autogenDir},
|
||||
|
@ -210,10 +211,13 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
|
|||
}
|
||||
|
||||
function findConventionalCategoryDocLink(): SidebarItemDoc | undefined {
|
||||
return allItems.find(
|
||||
(item) =>
|
||||
item.type === 'doc' && isConventionalDocIndex(getDoc(item.id)),
|
||||
) as SidebarItemDoc | undefined;
|
||||
return allItems.find((item) => {
|
||||
if (item.type !== 'doc') {
|
||||
return false;
|
||||
}
|
||||
const doc = getDoc(item.id);
|
||||
return isCategoryIndex(toCategoryIndexMatcherParam(doc));
|
||||
}) as SidebarItemDoc | undefined;
|
||||
}
|
||||
|
||||
function getCategoryLinkedDocId(): string | undefined {
|
||||
|
|
|
@ -25,6 +25,7 @@ import {DefaultSidebarItemsGenerator} from './generator';
|
|||
import {mapValues, memoize, pick} from 'lodash';
|
||||
import combinePromises from 'combine-promises';
|
||||
import {normalizeItem} from './normalization';
|
||||
import {isCategoryIndex} from '../docs';
|
||||
import type {Slugger} from '@docusaurus/utils';
|
||||
import type {
|
||||
NumberPrefixParser,
|
||||
|
@ -95,6 +96,7 @@ async function processSidebar(
|
|||
item,
|
||||
numberPrefixParser,
|
||||
defaultSidebarItemsGenerator: DefaultSidebarItemsGenerator,
|
||||
isCategoryIndex,
|
||||
...getSidebarItemsGeneratorDocsAndVersion(),
|
||||
options: sidebarOptions,
|
||||
});
|
||||
|
|
|
@ -10,6 +10,7 @@ import type {DocMetadataBase, VersionMetadata} from '../types';
|
|||
import type {
|
||||
NumberPrefixParser,
|
||||
SidebarOptions,
|
||||
CategoryIndexMatcher,
|
||||
} from '@docusaurus/plugin-content-docs';
|
||||
|
||||
// Makes all properties visible when hovering over the type
|
||||
|
@ -195,6 +196,7 @@ export type SidebarItemsGeneratorArgs = {
|
|||
version: SidebarItemsGeneratorVersion;
|
||||
docs: SidebarItemsGeneratorDoc[];
|
||||
numberPrefixParser: NumberPrefixParser;
|
||||
isCategoryIndex: CategoryIndexMatcher;
|
||||
options: SidebarOptions;
|
||||
};
|
||||
export type SidebarItemsGenerator = (
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue