mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-19 11:12:36 +02:00
feat(content-docs): autogenerate category with linked doc metadata as fallback (#6859)
This commit is contained in:
parent
f1bcdbff63
commit
b5ceead3b2
8 changed files with 62 additions and 23 deletions
|
@ -116,7 +116,7 @@ exports[`DefaultSidebarItemsGenerator generates subfolder sidebar 1`] = `
|
|||
"type": "doc",
|
||||
},
|
||||
],
|
||||
"label": "subsubsubfolder3 (_category_.json label)",
|
||||
"label": "Subsubsubfolder category label",
|
||||
"link": {
|
||||
"id": "doc1",
|
||||
"type": "doc",
|
||||
|
|
|
@ -234,7 +234,7 @@ describe('DefaultSidebarItemsGenerator', () => {
|
|||
},
|
||||
'subfolder/subsubfolder/subsubsubfolder3': {
|
||||
position: 1,
|
||||
label: 'subsubsubfolder3 (_category_.json label)',
|
||||
// This item's label is defined from the index doc instead
|
||||
link: {
|
||||
type: 'doc',
|
||||
id: 'doc1', // This is a "fully-qualified" ID that can't be found locally
|
||||
|
@ -246,6 +246,7 @@ describe('DefaultSidebarItemsGenerator', () => {
|
|||
id: 'doc1',
|
||||
source: 'doc1.md',
|
||||
sourceDirName: 'subfolder/subsubfolder',
|
||||
title: 'Subsubsubfolder category label',
|
||||
sidebarPosition: undefined,
|
||||
frontMatter: {},
|
||||
},
|
||||
|
|
|
@ -158,9 +158,6 @@ Available doc IDs:
|
|||
): WithPosition<NormalizedSidebarItemCategory> {
|
||||
const categoryMetadata =
|
||||
categoriesMetadata[posixPath(path.join(autogenDir, fullPath))];
|
||||
const className = categoryMetadata?.className;
|
||||
const customProps = categoryMetadata?.customProps;
|
||||
const {filename, numberPrefix} = numberPrefixParser(folderName);
|
||||
const allItems = Object.entries(dir).map(([key, content]) =>
|
||||
dirToItem(content, key, `${fullPath}/${key}`),
|
||||
);
|
||||
|
@ -184,41 +181,65 @@ Available doc IDs:
|
|||
});
|
||||
}
|
||||
|
||||
function getCategoryLinkedDocId(): string | undefined {
|
||||
const link = categoryMetadata?.link;
|
||||
if (link !== undefined) {
|
||||
if (link && link.type === 'doc') {
|
||||
return findDocByLocalId(link.id)?.id || getDoc(link.id).id;
|
||||
// In addition to the ID, this function also retrieves metadata of the
|
||||
// linked doc that could be used as fallback values for category metadata
|
||||
function getCategoryLinkedDocMetadata():
|
||||
| {
|
||||
id: string;
|
||||
position?: number;
|
||||
label?: string;
|
||||
customProps?: {[key: string]: unknown};
|
||||
className?: string;
|
||||
}
|
||||
| undefined {
|
||||
const link = categoryMetadata?.link;
|
||||
if (link !== undefined && link?.type !== 'doc') {
|
||||
// If a link is explicitly specified, we won't apply conventions
|
||||
return undefined;
|
||||
}
|
||||
// Apply default convention to pick index.md, README.md or
|
||||
// <categoryName>.md as the category doc
|
||||
return findConventionalCategoryDocLink()?.id;
|
||||
const id = link
|
||||
? findDocByLocalId(link.id)?.id ?? getDoc(link.id).id
|
||||
: findConventionalCategoryDocLink()?.id;
|
||||
if (!id) {
|
||||
return undefined;
|
||||
}
|
||||
const doc = getDoc(id);
|
||||
return {
|
||||
id,
|
||||
position: doc.sidebarPosition,
|
||||
label: doc.frontMatter.sidebar_label ?? doc.title,
|
||||
customProps: doc.frontMatter.sidebar_custom_props,
|
||||
className: doc.frontMatter.sidebar_class_name,
|
||||
};
|
||||
}
|
||||
|
||||
const categoryLinkedDocId = getCategoryLinkedDocId();
|
||||
|
||||
const categoryLinkedDoc = getCategoryLinkedDocMetadata();
|
||||
const link: SidebarItemCategoryLinkConfig | null | undefined =
|
||||
categoryLinkedDocId
|
||||
categoryLinkedDoc
|
||||
? {
|
||||
type: 'doc',
|
||||
id: categoryLinkedDocId, // We "remap" a potentially "local id" to a "qualified id"
|
||||
id: categoryLinkedDoc.id, // We "remap" a potentially "local id" to a "qualified id"
|
||||
}
|
||||
: categoryMetadata?.link;
|
||||
|
||||
// If a doc is linked, remove it from the category subItems
|
||||
const items = allItems.filter(
|
||||
(item) => !(item.type === 'doc' && item.id === categoryLinkedDocId),
|
||||
(item) => !(item.type === 'doc' && item.id === categoryLinkedDoc?.id),
|
||||
);
|
||||
|
||||
const className =
|
||||
categoryMetadata?.className ?? categoryLinkedDoc?.className;
|
||||
const customProps =
|
||||
categoryMetadata?.customProps ?? categoryLinkedDoc?.customProps;
|
||||
const {filename, numberPrefix} = numberPrefixParser(folderName);
|
||||
|
||||
return {
|
||||
type: 'category',
|
||||
label: categoryMetadata?.label ?? filename,
|
||||
label: categoryMetadata?.label ?? categoryLinkedDoc?.label ?? filename,
|
||||
collapsible: categoryMetadata?.collapsible,
|
||||
collapsed: categoryMetadata?.collapsed,
|
||||
position: categoryMetadata?.position ?? numberPrefix,
|
||||
position:
|
||||
categoryMetadata?.position ??
|
||||
categoryLinkedDoc?.position ??
|
||||
numberPrefix,
|
||||
source: folderName,
|
||||
...(customProps !== undefined && {customProps}),
|
||||
...(className !== undefined && {className}),
|
||||
|
|
|
@ -31,6 +31,7 @@ function toSidebarItemsGeneratorDoc(
|
|||
return _.pick(doc, [
|
||||
'id',
|
||||
'unversionedId',
|
||||
'title',
|
||||
'frontMatter',
|
||||
'source',
|
||||
'sourceDirName',
|
||||
|
|
|
@ -231,6 +231,7 @@ export type SidebarItemsGeneratorDoc = Pick<
|
|||
DocMetadataBase,
|
||||
| 'id'
|
||||
| 'unversionedId'
|
||||
| 'title'
|
||||
| 'frontMatter'
|
||||
| 'source'
|
||||
| 'sourceDirName'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue