Skip to content

Commit

Permalink
Add ability to specify sub categories in sidebar.json
Browse files Browse the repository at this point in the history
  • Loading branch information
WillBrock authored and endiliey committed Oct 8, 2018
1 parent d052fee commit df615c6
Show file tree
Hide file tree
Showing 14 changed files with 531 additions and 84 deletions.
23 changes: 23 additions & 0 deletions docs/guides-navigation.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,29 @@ You should provide `directory/id` instead of `id` in `sidebars.json`.
}
```

### Adding Sub Categories

It is possibile to add sub categories to a sidebar. Instead of passing an array to the category like the previous examples you can pass an object where
the keys will be the sub category name. You can then pass an array of document ids to the sub category.

```js
{
"examples-sidebar" : {
"My Example Category" : {
"My Example Sub Category" : [
"my-examples",
...
],
"My Next Sub Category" : [
"some-other-examples"
]
...
},
...
}
}
```

### Adding New Sidebars

You can also put a document in a new sidebar. In the following example, we are creating an `examples-sidebar` sidebar within `sidebars.json` that has a category called `My Example Category` containing a document with an `id` of `my-examples`.
Expand Down
65 changes: 65 additions & 0 deletions lib/server/__tests__/__fixtures__/metadata-subcategories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
module.exports = {
'en-doc1': {
id: 'en-doc1',
title: 'Document 1',
source: 'doc1.md',
version: 'next',
permalink: 'docs/en/next/doc1.html',
localized_id: 'doc1',
language: 'en',
sidebar: 'docs',
category: 'Test',
next_id: 'doc2',
next: 'en-doc2',
next_title: 'Document 2',
sub_category: 'Sub Cat 1',
sort: 1,
},
'en-doc2': {
id: 'en-doc2',
title: 'Document 2',
source: 'doc2.md',
version: 'next',
permalink: 'docs/en/next/doc2.html',
localized_id: 'doc2',
language: 'en',
sidebar: 'docs',
category: 'Test',
previous_id: 'doc1',
previous: 'en-doc1',
previous_title: 'Document 1',
sub_category: 'Sub Cat 1',
sort: 2,
},
'en-doc3': {
id: 'en-doc3',
title: 'Document 3',
source: 'doc3.md',
version: 'next',
permalink: 'docs/en/next/doc3.html',
localized_id: 'doc3',
language: 'en',
sidebar: 'docs',
category: 'Test',
previous_id: 'doc2',
previous: 'en-doc2',
previous_title: 'Document 2',
sub_category: 'Sub Cat 2',
sort: 3,
},
'en-doc4': {
id: 'en-doc4',
title: 'Document 4',
source: 'doc4.md',
version: 'next',
permalink: 'docs/en/next/doc4.html',
localized_id: 'doc4',
language: 'en',
sidebar: 'docs',
category: 'Test 2',
previous_id: 'doc3',
previous: 'en-doc3',
previous_title: 'Document 3',
sort: 4,
},
};
11 changes: 11 additions & 0 deletions lib/server/__tests__/__fixtures__/sidebar-subcategories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = {
docs: {
'First Category': {
'Sub Cat One': ['doc2', 'doc1'],
'Sub Cat Two': ['doc3', 'doc5'],
},
'Second Category': {
Hello: ['doc4'],
},
},
};
6 changes: 6 additions & 0 deletions lib/server/__tests__/__fixtures__/sidebar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
docs: {
'First Category': ['doc1', 'doc2'],
'Second Category': ['doc4', 'doc3'],
},
};
91 changes: 91 additions & 0 deletions lib/server/__tests__/readCategories.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* 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.
*/

const readCategories = require('../readCategories');
const generalMetadata = require('./__fixtures__/metadata.js');
const subCategoryMetadata = require('./__fixtures__/metadata-subcategories.js');

const languages = [
{
enabled: true,
name: 'English',
tag: 'en',
},
{
enabled: true,
name: 'Foo',
tag: 'ko',
},
];

const languagesMultiple = [
{
enabled: false,
name: 'English',
tag: 'en',
},
{
enabled: true,
name: 'Foo',
tag: 'ko',
},
];

describe('readCategories', () => {
test('should return proper categories and their pages', () => {
const categories = readCategories('docs', generalMetadata, languages);

expect(categories.en).toBeDefined();
expect(categories.en.length).toBe(2);

expect(categories.en[0].name).toBe('Test');
expect(categories.en[0].links.length).toBe(2);
expect(categories.en[0].links[0].id).toBe('en-doc1');
expect(categories.en[0].links[1].id).toBe('en-doc2');

expect(categories.en[1].name).toBe('Test 2');
expect(categories.en[1].links.length).toBe(1);
expect(categories.en[1].links[0].id).toBe('en-doc3');
});

test('should return proper data with categories and sub categories', () => {
const categories = readCategories('docs', subCategoryMetadata, languages);

expect(categories.en).toBeDefined();
expect(categories.ko).toBeDefined();
expect(categories.en.length).toBe(2);

expect(categories.en[0].name).toBe('Test');
expect(categories.en[0].links.length).toBe(0);
expect(categories.en[0].sub_categories.length).toBe(2);

expect(categories.en[0].sub_categories[0].name).toBe('Sub Cat 1');
expect(categories.en[0].sub_categories[0].links.length).toBe(2);
expect(categories.en[0].sub_categories[0].links[0].id).toBe('en-doc1');
expect(categories.en[0].sub_categories[0].links[1].id).toBe('en-doc2');

expect(categories.en[0].sub_categories[1].name).toBe('Sub Cat 2');
expect(categories.en[0].sub_categories[1].links.length).toBe(1);
expect(categories.en[0].sub_categories[1].links[0].id).toBe('en-doc3');

expect(categories.en[1].name).toBe('Test 2');
expect(categories.en[1].links.length).toBe(1);
expect(categories.en[1].links[0].id).toBe('en-doc4');
expect(categories.en[1].sub_categories).not.toBeDefined();
});

test('should return proper languages when not enabled', () => {
const categories = readCategories(
'docs',
generalMetadata,
languagesMultiple
);

expect(categories.en).not.toBeDefined();
expect(categories.ko).toBeDefined();
});
});
77 changes: 77 additions & 0 deletions lib/server/__tests__/readMetadata.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* 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.
*/

const {readSidebar} = require('../readMetadata');
const sidebar = require('./__fixtures__/sidebar');
const sidebarSubCategories = require('./__fixtures__/sidebar-subcategories');

jest.mock('../env', () => ({
translation: {
enabled: true,
enabledLanguages: () => [
{
enabled: true,
name: 'English',
tag: 'en',
},
{
enabled: true,
name: '한국어',
tag: 'ko',
},
],
},
versioning: {
enabled: true,
defaultVersion: '1.0.0',
},
}));

jest.mock(`${process.cwd()}/siteConfig.js`, () => true, {virtual: true});
jest.mock(`${process.cwd()}/sidebar.json`, () => true, {virtual: true});

describe('readMetadata', () => {
describe('readSidebar', () => {
it('should verify regular category data and verify sort', () => {
const order = readSidebar(sidebar);

// Put in this order to verify sort
['doc1', 'doc2', 'doc4', 'doc3'].forEach((id, index) => {
expect(order[id]).toBeDefined();
expect(order[id].sort).toBe(index + 1);
});

expect(order.doc1.previous).toBeUndefined();
expect(order.doc2.previous).toBe('doc1');

expect(order.doc1.next).toBe('doc2');
expect(order.doc2.next).toBe('doc4');

expect(order.doc1.sub_category).toBeFalsy();
});

test('should verify sub category data and verify sort', () => {
const order = readSidebar(sidebarSubCategories);

// Put in this order to verify sort
['doc2', 'doc1', 'doc3', 'doc5', 'doc4'].forEach((id, index) => {
expect(order[id]).toBeDefined();
expect(order[id].sort).toBe(index + 1);
});

expect(order.doc2.sidebar).toBe('docs');
expect(order.doc2.category).toBe('First Category');
expect(order.doc2.sub_category).toBe('Sub Cat One');

expect(order.doc1.category).toBe('First Category');
expect(order.doc1.sub_category).toBe('Sub Cat One');

expect(order.doc3.category).toBe('First Category');
expect(order.doc3.sub_category).toBe('Sub Cat Two');
});
});
});
18 changes: 17 additions & 1 deletion v1/lib/core/DocsSidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,30 @@
*/

const React = require('react');
const fs = require('fs');
const Container = require('./Container.js');
const SideNav = require('./nav/SideNav.js');
const Metadata = require('../core/metadata.js');
const readCategories = require('../server/readCategories.js');

let languages;

if (fs.existsSync(`../server/languages.js`)) {
languages = require(`../server/languages.js`);
} else {
languages = [
{
enabled: true,
name: 'English',
tag: 'en',
},
];
}

class DocsSidebar extends React.Component {
render() {
const sidebar = this.props.metadata.sidebar;
const docsCategories = readCategories(sidebar);
const docsCategories = readCategories(sidebar, Metadata, languages);
const categoryName = docsCategories[this.props.metadata.language][0].name;
if (!categoryName) {
return null;
Expand Down
17 changes: 16 additions & 1 deletion v1/lib/core/nav/SideNav.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,22 @@ class SideNav extends React.Component {
<h3 className="navGroupCategoryTitle">
{this.getLocalizedCategoryString(category.name)}
</h3>
<ul>{category.links.map(this.renderItemLink, this)}</ul>
<ul>
{category.links.map(this.renderItemLink, this)}
{category.sub_categories &&
category.sub_categories.map(this.renderSubCategory, this)}
</ul>
</div>
);
}

renderSubCategory(subCategory) {
return (
<div className="navGroup subNavGroup" key={subCategory.name}>
<h4 className="navGroupSubCategoryTitle">
{this.getLocalizedCategoryString(subCategory.name)}
</h4>
<ul>{subCategory.links.map(this.renderItemLink, this)}</ul>
</div>
);
}
Expand Down
17 changes: 17 additions & 0 deletions v1/lib/server/__tests__/__fixtures__/metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module.exports = {
next_id: 'doc2',
next: 'en-doc2',
next_title: 'Document 2',
sort: 1,
},
'en-doc2': {
id: 'en-doc2',
Expand All @@ -26,6 +27,22 @@ module.exports = {
previous_id: 'doc1',
previous: 'en-doc1',
previous_title: 'Document 1',
sort: 2,
},
'en-doc3': {
id: 'en-doc3',
title: 'Document 3',
source: 'doc3.md',
version: 'next',
permalink: 'docs/en/next/doc3.html',
localized_id: 'doc3',
language: 'en',
sidebar: 'docs',
category: 'Test 2',
previous_id: 'doc2',
previous: 'en-doc2',
previous_title: 'Document 2',
sort: 3,
},
'ko-doc1': {
id: 'ko-doc1',
Expand Down
Loading

0 comments on commit df615c6

Please sign in to comment.