Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(v2): auto-generated sidebars, frontmatter-less sites #4582

Merged
merged 53 commits into from
Apr 15, 2021
Merged
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
46fb9ca
POC of autogenerated sidebars
slorber Apr 6, 2021
749a251
use combine-promises utility lib
slorber Apr 7, 2021
c81da98
autogenerated sidebar poc working
slorber Apr 7, 2021
b39231f
Revert "autogenerated sidebar poc working"
slorber Apr 7, 2021
e4dd084
POC of auto-generated sidebars for community docs
slorber Apr 7, 2021
c285c65
update tests
slorber Apr 7, 2021
69da2a1
add initial test suite for autogenerated sidebars + fix some edge cases
slorber Apr 8, 2021
9a6904b
Improve autogen sidebars: strip more number prefixes in folder breadc…
slorber Apr 8, 2021
15e3f4b
fix typo!
slorber Apr 8, 2021
6034b64
Add tests for partially generated sidebars + fix edge cases + extract…
slorber Apr 8, 2021
5224653
Ability to read category metadatas file from a file in the category
slorber Apr 8, 2021
3175db0
Merge branch 'master' into slorber/autogen-sidebars
slorber Apr 9, 2021
1bd562b
fix tests
slorber Apr 10, 2021
abf9b0b
change position of API
slorber Apr 10, 2021
3d55863
ability to extract number prefix
slorber Apr 10, 2021
d49d2e3
stable system to enable position frontmatter
slorber Apr 10, 2021
5a4487d
fix tests for autogen sidebar position
slorber Apr 11, 2021
69c83ea
Merge branch 'master' into slorber/autogen-sidebars
slorber Apr 13, 2021
58fa9a2
renamings
slorber Apr 13, 2021
0f96a74
restore community sidebars
slorber Apr 13, 2021
e41b43f
rename frontmatter position -> sidebar_position
slorber Apr 13, 2021
732b25c
make sidebarItemsGenerator fn configurable
slorber Apr 13, 2021
e5e48ae
minor changes
slorber Apr 13, 2021
6d3ded3
rename dirPath => dirName
slorber Apr 13, 2021
56d2e75
Make the init template use autogenerated sidebars
slorber Apr 13, 2021
f3f3d12
fix options
slorber Apr 13, 2021
0f225d9
fix docusaurus site: remove test docs
slorber Apr 13, 2021
77e61da
add _category_ file to docs pathsToWatch
slorber Apr 13, 2021
eceb7ad
add _category_ file to docs pathsToWatch
slorber Apr 13, 2021
6c57520
tutorial: use sidebar_position instead of file number prefixes
slorber Apr 13, 2021
61bfa2e
Adapt Docusaurus tutorial for autogenerated sidebars
slorber Apr 13, 2021
117c528
remove slug: /
slorber Apr 13, 2021
6ef4a61
polish the homepage template
slorber Apr 13, 2021
8a11816
rename _category_ sidebar_position to just "position"
slorber Apr 13, 2021
cbfab8c
test for custom sidebarItemsGenerator fn
slorber Apr 13, 2021
1ace81e
fix category metadata + add link to report tutorial issues
slorber Apr 13, 2021
3a27c3e
Merge branch 'master' into slorber/autogen-sidebars
slorber Apr 14, 2021
177a41a
fix absolute path breaking tests
slorber Apr 14, 2021
35282fa
fix absolute path breaking tests
slorber Apr 14, 2021
db806b1
Add test for floating number sidebar_position
slorber Apr 14, 2021
1a48e23
add sidebarItemsGenerator unit tests
slorber Apr 14, 2021
c7d09e6
add processSidebars unit tests
slorber Apr 14, 2021
9705029
Fix init template broken links
slorber Apr 14, 2021
2f5fdd4
windows test
slorber Apr 14, 2021
727903d
increase code translations test timeout
slorber Apr 14, 2021
7ca2ff7
cleanup mockCategoryMetadataFiles after windows test fixed
slorber Apr 14, 2021
4662610
Merge branch 'master' into slorber/autogen-sidebars
slorber Apr 14, 2021
cee22a7
update init template positions
slorber Apr 14, 2021
5acb3d1
fix windows tests
slorber Apr 14, 2021
827a4cb
fix comment
slorber Apr 14, 2021
e240448
Add autogenerated sidebar items documentation + rewrite the full side…
slorber Apr 15, 2021
87102f6
add useful comment
slorber Apr 15, 2021
f23e823
fix code block title
slorber Apr 15, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
stable system to enable position frontmatter
slorber committed Apr 10, 2021

Verified

This commit was signed with the committer’s verified signature.
Eliulm Elias Wahl
commit d49d2e3d68962517f2eb8b4027a32c4316687e17
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
id: guide2
---

Guide 2
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"position": 2
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
id: guide4
---

Guide 4
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
id: guide5
---

Guide 5
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
id: guide3
position: 3
---

Guide 3
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
id: guide1
position: 1
---

Guide 1
60 changes: 44 additions & 16 deletions packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
@@ -751,7 +751,7 @@ describe('site with doc label', () => {
});
});

describe('site with full autogenerated sidebar', () => {
describe.only('site with full autogenerated sidebar', () => {
async function loadSite() {
const siteDir = path.join(
__dirname,
@@ -771,64 +771,92 @@ describe('site with full autogenerated sidebar', () => {
return {content, siteDir};
}

test('sidebar is fully autogenerated', async () => {
test.only('sidebar is fully autogenerated', async () => {
const {content} = await loadSite();
const version = content.loadedVersions[0];

expect(version.sidebars).toEqual({
defaultSidebar: [
{
id: 'getting-started',
type: 'doc',
id: 'getting-started',
},
{
id: 'installation',
type: 'doc',
id: 'installation',
},
{
type: 'category',
label: 'Guides',
collapsed: true,
items: [
{
type: 'doc',
id: 'Guides/guide1',
},
{
type: 'doc',
id: 'Guides/guide2',
},
{
type: 'doc',
id: 'Guides/guide3',
},
{
type: 'doc',
id: 'Guides/guide4',
},
{
type: 'doc',
id: 'Guides/guide5',
},
],
},
{
type: 'category',
label: 'API (label from _category_.json)',
collapsed: true,
items: [
{
id: 'API/api-overview',
type: 'doc',
id: 'API/api-overview',
},
{
type: 'category',
label: 'Core APIs',
collapsed: true,
items: [
{
id: 'API/Core APIs/Client API',
type: 'doc',

id: 'API/Core APIs/Client API',
},
{
id: 'API/Core APIs/Server API',
type: 'doc',
id: 'API/Core APIs/Server API',
},
],
label: 'Core APIs',
type: 'category',
},
{
type: 'category',
label: 'Extension APIs (label from _category_.yml)',
collapsed: true,
items: [
{
id: 'API/Extension APIs/Plugin API',
type: 'doc',
id: 'API/Extension APIs/Plugin API',
},
{
id: 'API/Extension APIs/Theme API',
type: 'doc',
id: 'API/Extension APIs/Theme API',
},
],
label: 'Extension APIs (label from _category_.yml)',
type: 'category',
},
{
id: 'API/api-end',
type: 'doc',
id: 'API/api-end',
},
],
label: 'API (label from _category_.json)',
type: 'category',
},
],
});
Original file line number Diff line number Diff line change
@@ -69,6 +69,10 @@ describe('stripPathNumberPrefix', () => {

describe('extractNumberPrefix', () => {
test('should extract number prefix if present', () => {
expect(extractNumberPrefix('0-My Doc')).toEqual({
filename: 'My Doc',
numberPrefix: 0,
});
expect(extractNumberPrefix('1-My Doc')).toEqual({
filename: 'My Doc',
numberPrefix: 1,
2 changes: 2 additions & 0 deletions packages/docusaurus-plugin-content-docs/src/docFrontMatter.ts
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ type DocFrontMatter = {
description?: string;
slug?: string;
sidebar_label?: string;
position?: number;
custom_edit_url?: string;
strip_number_prefixes: boolean;
};
@@ -24,6 +25,7 @@ const DocFrontMatterSchema = Joi.object<DocFrontMatter>({
description: Joi.string(),
slug: Joi.string(),
sidebar_label: Joi.string(),
position: Joi.number(),
custom_edit_url: Joi.string().allow(null),
strip_number_prefixes: Joi.boolean(),
}).unknown();
17 changes: 11 additions & 6 deletions packages/docusaurus-plugin-content-docs/src/docs.ts
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ import getSlug from './slug';
import {CURRENT_VERSION_NAME} from './constants';
import globby from 'globby';
import {getDocsDirPaths} from './versions';
import {stripNumberPrefix, stripPathNumberPrefixes} from './numberPrefix';
import {extractNumberPrefix, stripPathNumberPrefixes} from './numberPrefix';
import {assertDocFrontMatter} from './docFrontMatter';

type LastUpdateOptions = Pick<
@@ -142,15 +142,19 @@ export function processDocMetadata({
// ex: myDoc -> .
const sourceDirName = path.dirname(source);

const baseID: string =
frontMatter.id ||
(stripNumberPrefixes
? stripNumberPrefix(sourceFileNameWithoutExtension)
: sourceFileNameWithoutExtension);
const {filename: unprefixedFileName, numberPrefix} = stripNumberPrefixes
? extractNumberPrefix(sourceFileNameWithoutExtension)
: {filename: sourceFileNameWithoutExtension, numberPrefix: undefined};

const baseID: string = frontMatter.id ?? unprefixedFileName;
if (baseID.includes('/')) {
throw new Error(`Document id [${baseID}] cannot include "/".`);
}

// For autogenerated sidebars, sidebar position can come from filename number prefix or frontmatter
const sidebarPosition: number | undefined =
frontMatter.position ?? numberPrefix;

// TODO legacy retrocompatibility
// The same doc in 2 distinct version could keep the same id,
// we just need to namespace the data by version
@@ -252,6 +256,7 @@ export function processDocMetadata({
)
: undefined,
sidebar_label: sidebarLabel,
position: sidebarPosition,
frontMatter,
};
}
Original file line number Diff line number Diff line change
@@ -12,10 +12,10 @@ import {
DocMetadataBase,
SidebarItemsGenerator,
} from './types';
import {sortBy, take, last} from 'lodash';
import {sortBy, take, last, orderBy} from 'lodash';
import {addTrailingSlash} from '@docusaurus/utils';
import {Joi} from '@docusaurus/utils-validation';
import {stripNumberPrefix} from './numberPrefix';
import {extractNumberPrefix} from './numberPrefix';
import chalk from 'chalk';
import path from 'path';
import fs from 'fs-extra';
@@ -28,6 +28,9 @@ type CategoryMetadatasFile = {
position?: number; // TODO handle it! sort category items
};

type WithPosition = {position?: number};
type SidebarItemWithPosition = SidebarItem & WithPosition;

const CategoryMetadatasFileSchema = Joi.object<CategoryMetadatasFile>({
label: Joi.string().optional(),
position: Joi.number().optional(),
@@ -86,7 +89,7 @@ function parseBreadcrumb(

// TODO allow to customize this logic (docs cfg+sidebar.js)
// TODO define and document proper API surface
export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = ({
export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
item,
docs: allDocs,
version,
@@ -168,23 +171,26 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = ({
);
*/

function createDocSidebarItem(doc: DocMetadataBase): SidebarItemDoc {
function createDocSidebarItem(
doc: DocMetadataBase,
): SidebarItemDoc & WithPosition {
return {
type: 'doc',
id: doc.id,
...(doc.frontMatter.sidebar_label && {
label: doc.frontMatter.sidebar_label,
}),
...(typeof doc.position !== 'undefined' && {
position: doc.position,
}),
};
}

async function createCategorySidebarItem({
breadcrumb,
}: {
breadcrumb: string[];
}): Promise<SidebarItemCategory> {
// TODO read metadata file from the directory for additional config?

}): Promise<SidebarItemCategory & WithPosition> {
const categoryDirPath = path.join(
version.contentPath,
breadcrumb.join(BreadcrumbSeparator),
@@ -194,16 +200,23 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = ({

const {tail} = parseBreadcrumb(breadcrumb);

const {filename, numberPrefix} = extractNumberPrefix(tail);

const position = categoryMetadatas?.position ?? numberPrefix;

return {
type: 'category',
label: categoryMetadatas?.label ?? stripNumberPrefix(tail),
label: categoryMetadatas?.label ?? filename,
items: [],
collapsed: true, // TODO use default value
...(typeof position !== 'undefined' && {position}),
};
}

// Not sure how to simplify this algorithm :/
async function autogenerateSidebarItems(): Promise<SidebarItem[]> {
async function autogenerateSidebarItems(): Promise<
SidebarItemWithPosition[]
> {
const sidebarItems: SidebarItem[] = []; // mutable result

const categoriesByBreadcrumb: Record<string, SidebarItemCategory> = {}; // mutable cache of categories already created
@@ -270,5 +283,38 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = ({
return sidebarItems;
}

return autogenerateSidebarItems();
const sidebarItems = await autogenerateSidebarItems();

/*
console.log({
unsorted: sidebarItems,
sorted: sortSidebarItems(sidebarItems),
});
*/

return sortSidebarItems(sidebarItems);
};

// Recursively sort the categories/docs + remove the "position" attribute from final output
function sortSidebarItems(
sidebarItems: SidebarItemWithPosition[],
): SidebarItem[] {
const processedSidebarItems = sidebarItems.map((item) => {
if (item.type === 'category') {
return {
...item,
items: sortSidebarItems(item.items),
};
}
return item;
});

const sortedSidebarItems = orderBy(
processedSidebarItems,
(item) => item.position,
['asc'],
);

return sortedSidebarItems.map(({position: _removed, ...item}) => item);
}
1 change: 1 addition & 0 deletions packages/docusaurus-plugin-content-docs/src/types.ts
Original file line number Diff line number Diff line change
@@ -173,6 +173,7 @@ export type DocMetadataBase = LastUpdateData & {
permalink: string;
// eslint-disable-next-line camelcase
sidebar_label?: string;
position?: number;
editUrl?: string | null;
frontMatter: FrontMatter;
};