mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-03 11:22:30 +02:00
feat(v2): allow infinitely nested sidebar (#1812)
* feat(v2): allow infinitely nested sidebar * Update markdown-features.mdx * Update sidebar.md * Update sidebar.md
This commit is contained in:
parent
1591128cdd
commit
95f0552bad
7 changed files with 282 additions and 41 deletions
|
@ -1,6 +1,9 @@
|
|||
# Docusaurus 2 Changelog
|
||||
|
||||
## Unreleased
|
||||
- Docs plugin is rewritten in TypeScript
|
||||
- Docs sidebar can now be more than one level deep, theoretically up to infinity.
|
||||
- more documentation ...
|
||||
|
||||
## 2.0.0-alpha.25
|
||||
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
docs: [
|
||||
{
|
||||
type: 'category',
|
||||
label: 'level 1',
|
||||
items: [
|
||||
'a',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'level 2',
|
||||
items: [
|
||||
{
|
||||
type: 'category',
|
||||
label: 'level 3',
|
||||
items: [
|
||||
'c',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'level 4',
|
||||
items: [
|
||||
'd',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'deeper more more',
|
||||
items: ['e'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
'f',
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
|
@ -1,5 +1,62 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`loadSidebars sidebars with deep level of category 1`] = `
|
||||
Object {
|
||||
"docs": Array [
|
||||
Object {
|
||||
"items": Array [
|
||||
Object {
|
||||
"id": "a",
|
||||
"type": "doc",
|
||||
},
|
||||
Object {
|
||||
"items": Array [
|
||||
Object {
|
||||
"items": Array [
|
||||
Object {
|
||||
"id": "c",
|
||||
"type": "doc",
|
||||
},
|
||||
Object {
|
||||
"items": Array [
|
||||
Object {
|
||||
"id": "d",
|
||||
"type": "doc",
|
||||
},
|
||||
Object {
|
||||
"items": Array [
|
||||
Object {
|
||||
"id": "e",
|
||||
"type": "doc",
|
||||
},
|
||||
],
|
||||
"label": "deeper more more",
|
||||
"type": "category",
|
||||
},
|
||||
],
|
||||
"label": "level 4",
|
||||
"type": "category",
|
||||
},
|
||||
],
|
||||
"label": "level 3",
|
||||
"type": "category",
|
||||
},
|
||||
Object {
|
||||
"id": "f",
|
||||
"type": "doc",
|
||||
},
|
||||
],
|
||||
"label": "level 2",
|
||||
"type": "category",
|
||||
},
|
||||
],
|
||||
"label": "level 1",
|
||||
"type": "category",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`loadSidebars sidebars with known sidebar item type 1`] = `
|
||||
Object {
|
||||
"docs": Array [
|
||||
|
|
|
@ -22,6 +22,17 @@ describe('loadSidebars', () => {
|
|||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('sidebars with deep level of category', async () => {
|
||||
const sidebarPath = path.join(
|
||||
__dirname,
|
||||
'__fixtures__',
|
||||
'website',
|
||||
'sidebars-category.js',
|
||||
);
|
||||
const result = loadSidebars(sidebarPath);
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('sidebars with unknown sidebar item type', async () => {
|
||||
const sidebarPath = path.join(
|
||||
__dirname,
|
||||
|
|
|
@ -40,14 +40,6 @@ function normalizeCategory(
|
|||
category: SidebarItemCategoryRaw,
|
||||
level = 0,
|
||||
): SidebarItemCategory {
|
||||
if (level === 2) {
|
||||
throw new Error(
|
||||
`Can not process ${
|
||||
category.label
|
||||
} category. Categories can be nested only one level deep.`,
|
||||
);
|
||||
}
|
||||
|
||||
assertItem(category, ['items', 'label']);
|
||||
|
||||
if (!Array.isArray(category.items)) {
|
||||
|
|
|
@ -143,6 +143,19 @@ I can write **Markdown** alongside my _JSX_!
|
|||
|
||||
You can also import your own components defined in other files or third-party components installed via npm! Check out the [MDX docs](https://mdxjs.com/) to see what other fancy stuff you can do with MDX.
|
||||
|
||||
### Referencing other documents
|
||||
|
||||
If you want to reference another document file, you should use the name of the document you want to reference. Docusaurus will convert the file path to be the final website path (and remove the `.md`).
|
||||
|
||||
For example, if you are in `doc2.md` and you want to reference `doc1.md` and `folder/doc3.md`:
|
||||
|
||||
```md
|
||||
I am referencing a [document](doc1.md).
|
||||
Reference to another [document in a folder](folder/doc3.md)
|
||||
```
|
||||
|
||||
One benefit of this approach is that the links to external files will still work if you are viewing the file on GitHub.
|
||||
|
||||
### Syntax highlighting
|
||||
|
||||
Code blocks are text blocks wrapped around by strings of 3 backticks. You may check out [this reference](https://github.com/mdx-js/specification) for specifications of MDX.
|
||||
|
|
|
@ -3,49 +3,180 @@ id: sidebar
|
|||
title: Sidebar
|
||||
---
|
||||
|
||||
To generate a sidebar to your Docusaurus site, you need to define a file that exports a JS module and pass that into the `@docusaurus/plugin-docs` plugin directly or via `@docusaurus/preset-classic`. If you are using the classic preset, you can find the `sidebars.js` under the root directory already created for you, so you may edit it directly for customization.
|
||||
To generate a sidebar to your Docusaurus site, you need to define a file that exports a sidebar object and pass that into the `@docusaurus/plugin-docs` plugin directly or via `@docusaurus/preset-classic`.
|
||||
|
||||
<!-- TODO: change classic template to use `sidebars.js` from json -->
|
||||
|
||||
```bash
|
||||
website # root directory of your site
|
||||
├── docs
|
||||
│ └── greeting.md
|
||||
├── docusaurus.config.js
|
||||
├── sidebars.js
|
||||
.
|
||||
```js
|
||||
// docusaurus.config.js
|
||||
module.exports = {
|
||||
// ...
|
||||
presets: [
|
||||
[
|
||||
'@docusaurus/preset-classic',
|
||||
{
|
||||
docs: {
|
||||
// Sidebars filepath relative to the site dir.
|
||||
sidebarPath: require.resolve('./sidebars.js'),
|
||||
},
|
||||
...
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
To add a doc to the sidebar, add the `id` specified in the frontmatter of the doc into its category.
|
||||
## Sidebar object
|
||||
|
||||
```diff
|
||||
A sidebar object looks like the following. The key `docs` is the name of the sidebar (can be renamed to something else) and `Getting Started` is a category within the sidebar. `greeting` and `doc1` is just a [Sidebar Item](#sidebar-item).
|
||||
|
||||
```js
|
||||
// sidebars.js
|
||||
module.exports = {
|
||||
docs: {
|
||||
+ "Getting started": ["greeting"],
|
||||
"Docusaurus": ["doc1"],
|
||||
"First Category": ["doc2"],
|
||||
"Second Category": ["doc3"],
|
||||
'Getting started': ['greeting'],
|
||||
'Docusaurus': ['doc1'],
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
The `docs` key in the exported object is just the name of that particular sidebar hierarchy, and can be renamed to something else. You can have multiple sidebars for different Markdown files by adding more top-level keys to the exported object.
|
||||
If you don't want to rely on iteration order of JavaScript object keys for the category name, the following sidebar object is also equivalent of the above.
|
||||
|
||||
## Subcategories
|
||||
```js
|
||||
// sidebars.js
|
||||
module.exports = {
|
||||
docs: [
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Getting Started',
|
||||
items: ['greeting']
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Docusaurus',
|
||||
items: ['doc1']
|
||||
},
|
||||
]
|
||||
};
|
||||
```
|
||||
|
||||
To include subcategories in docs sidebar, use an object of the following shape
|
||||
You can also have multiple sidebars for different Markdown files by adding more top-level keys to the exported object.
|
||||
|
||||
Example:
|
||||
```js
|
||||
// sidebars.js
|
||||
module.exports = {
|
||||
firstSidebar: {
|
||||
'Category A': ['doc1'],
|
||||
},
|
||||
secondSidebar: {
|
||||
'Category A': ['doc2'],
|
||||
'Category B': ['doc3'],
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Document ID
|
||||
|
||||
Every document has a unique `id`. By default, a document `id` is the name of the document (without the extension) relative to the root docs directory.
|
||||
|
||||
For example, `greeting.md` id is `greeting` and `guide/hello.md` id is `guide/hello`.
|
||||
|
||||
```bash
|
||||
website # root directory of your site
|
||||
├── docs
|
||||
└── greeting.md
|
||||
└── guide
|
||||
└── hello.md
|
||||
```
|
||||
|
||||
However, the last part of the `id` can be defined by user in the frontmatter. For example, if `guide/hello.md` content is defined as below, it's final `id` is `guide/part1`.
|
||||
|
||||
```md
|
||||
---
|
||||
id: part1
|
||||
---
|
||||
Lorem ipsum
|
||||
```
|
||||
|
||||
## Sidebar item
|
||||
|
||||
As the name implies, `SidebarItem` is an item defined in a Sidebar. There are a few types we support:
|
||||
|
||||
- Doc
|
||||
- Link
|
||||
- Ref
|
||||
- Category
|
||||
|
||||
### Doc
|
||||
|
||||
Sidebar item type that links to a doc page. Example:
|
||||
|
||||
```js
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'doc1', // string - document id
|
||||
}
|
||||
```
|
||||
|
||||
Using just the [Document ID](#document-id) is perfectly valid as well, the following is equivalent to the above:
|
||||
|
||||
```js
|
||||
'doc1' // string - document id
|
||||
```
|
||||
|
||||
Note that using this type will bind the linked doc to current sidebar, this means that if you access `doc1` page, the sidebar displayed will be the sidebar this item is on. For below case, `doc1` is bounded to `firstSidebar`.
|
||||
|
||||
```js
|
||||
// sidebars.js
|
||||
module.exports = {
|
||||
firstSidebar: {
|
||||
'Category A': ['doc1'],
|
||||
},
|
||||
secondSidebar: {
|
||||
'Category A': ['doc2'],
|
||||
'Category B': ['doc3'],
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
### Link
|
||||
|
||||
Sidebar item type that links to a non-document page. Example:
|
||||
|
||||
```js
|
||||
{
|
||||
type: 'link',
|
||||
label: 'Custom Label', // string - the label that should be displayed.
|
||||
href: 'https://example.com' // string - the target URL.
|
||||
}
|
||||
```
|
||||
|
||||
### Ref
|
||||
|
||||
Sidebar item type that links to doc without bounding it to the sidebar. Example:
|
||||
|
||||
```js
|
||||
{
|
||||
type: 'ref',
|
||||
id: 'doc1', // string - document id
|
||||
}
|
||||
```
|
||||
|
||||
### Category
|
||||
|
||||
This is used to add hierarchies to the sidebar:
|
||||
|
||||
```js
|
||||
{
|
||||
type: 'category',
|
||||
label: string, // sidebar label
|
||||
items: string[], // strings of doc ids
|
||||
label: string, // Sidebar label text.
|
||||
items: SidebarItem[], // Array of sidebar items.
|
||||
}
|
||||
```
|
||||
|
||||
in place of a string of id. As an example, here's how we created the subcategory for "Docs" under "Guides" in this site:
|
||||
As an example, here's how we created the subcategory for "Docs" under "Guides" in this site:
|
||||
|
||||
```jsx
|
||||
```js
|
||||
// sidebars.js
|
||||
module.exports = {
|
||||
docs: {
|
||||
|
@ -60,13 +191,3 @@ module.exports = {
|
|||
},
|
||||
};
|
||||
```
|
||||
|
||||
**Note**: Only one layer of nestedness is allowed.
|
||||
|
||||
**Note**: We're implementing a new sidebar!
|
||||
|
||||
<!--
|
||||
|
||||
_This section is a work in progress. [Welcoming PRs](https://github.com/facebook/docusaurus/issues/1640)._
|
||||
|
||||
-->
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue