feat: doc tags (same as blog tags) (#3646)

* [v2] tags to doc, same as tags to blog - [IN PROGRESS]

- Addition of plugin-content-docs

- Addition of DocTagsListPage in `docusaurus-theme-classic`

! Error exists for this commit towards the theme aspect and help required.

Commit towards #3434

* docs: make tags list page work

* temp: disable onBrokenLinks

* theme bootstrap: create DocTagsListPage

* DocTagsPage added and functionality too

- individual doc tag page added to show docs for that specific tag

* Added all Docs Tags Link

* add some shared tag utils

* move tag tests to _dogfooding

* fix type

* fix some tests

* fix blog test

* refactor blog post tags handling

* better yaml tag examples

* better dogfood md files

* refactor and factorize theme tag components

* finish DocTagDocListPage

* Extract DocItemFooter + add inline tag list

* minor fix

* better typings

* fix versions.test.ts tests

* add tests for doc tags

* fix tests

* test toTagDocListProp

* move shared theme code to tagUtils

* Add new theme translation keys

* move common theme code to tagUtils + add tests

* update-code-translations should handle theme-common

* update french translation

* revert add translation

* fix pluralization problem in theme.docs.tagDocListPageTitle

* add theme component configuration options

* add more tags tests

* add documentation for docs tagging

Co-authored-by: slorber <lorber.sebastien@gmail.com>
This commit is contained in:
Isaac Philip 2021-08-19 14:01:15 +05:30 committed by GitHub
parent f666de7e59
commit f9c79cbd58
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
81 changed files with 1874 additions and 381 deletions

View file

@ -11,8 +11,12 @@ export const ThemeClassNames = {
blogListPage: 'blog-list-page',
blogPostPage: 'blog-post-page',
blogTagsListPage: 'blog-tags-list-page',
blogTagsPostPage: 'blog-tags-post-page',
docPage: 'doc-page',
blogTagPostListPage: 'blog-tags-post-list-page',
docsDocPage: 'docs-doc-page',
docsTagsListPage: 'docs-tags-list-page', // List of tags
docsTagDocListPage: 'docs-tags-doc-list-page', // Docs for a tag
mdxPage: 'mdx-page',
},
wrapper: {

View file

@ -0,0 +1,66 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {shuffle} from 'lodash';
import {listTagsByLetters} from '../tagsUtils';
describe('listTagsByLetters', () => {
type Param = Parameters<typeof listTagsByLetters>[0];
type Tag = Param[number];
type Result = ReturnType<typeof listTagsByLetters>;
test('Should create letters list', () => {
const tag1: Tag = {
name: 'tag1',
permalink: '/tag1',
count: 1,
};
const tag2: Tag = {
name: 'Tag2',
permalink: '/tag2',
count: 11,
};
const tagzxy: Tag = {
name: 'zxy',
permalink: '/zxy',
count: 987,
};
const tagAbc: Tag = {
name: 'Abc',
permalink: '/abc',
count: 123,
};
const tagdef: Tag = {
name: 'def',
permalink: '/def',
count: 1,
};
const tagaaa: Tag = {
name: 'aaa',
permalink: '/aaa',
count: 10,
};
const expectedResult: Result = [
{letter: 'A', tags: [tagaaa, tagAbc]},
{letter: 'D', tags: [tagdef]},
{letter: 'T', tags: [tag1, tag2]},
{letter: 'Z', tags: [tagzxy]},
];
// Input order shouldn't matter, output is always consistently sorted
expect(
listTagsByLetters([tag1, tag2, tagzxy, tagAbc, tagdef, tagaaa]),
).toEqual(expectedResult);
expect(
listTagsByLetters([tagzxy, tagdef, tagaaa, tag2, tagAbc, tag1]),
).toEqual(expectedResult);
expect(
listTagsByLetters(shuffle([tagzxy, tagdef, tagaaa, tag2, tagAbc, tag1])),
).toEqual(expectedResult);
});
});

View file

@ -0,0 +1,48 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {translate} from '@docusaurus/Translate';
export const translateTagsPageTitle = () =>
translate({
id: 'theme.tags.tagsPageTitle',
message: 'Tags',
description: 'The title of the tag list page',
});
type TagsListItem = Readonly<{name: string; permalink: string; count: number}>; // TODO remove duplicated type :s
export type TagLetterEntry = Readonly<{letter: string; tags: TagsListItem[]}>;
function getTagLetter(tag: string): string {
return tag[0].toUpperCase();
}
export function listTagsByLetters(
tags: readonly TagsListItem[],
): TagLetterEntry[] {
// Group by letters
const groups: Record<string, TagsListItem[]> = {};
Object.values(tags).forEach((tag) => {
const letter = getTagLetter(tag.name);
groups[letter] = groups[letter] ?? [];
groups[letter].push(tag);
});
return (
Object.entries(groups)
// Sort letters
.sort(([letter1], [letter2]) => letter1.localeCompare(letter2))
.map(([letter, letterTags]) => {
// Sort tags inside a letter
const sortedTags = letterTags.sort((tag1, tag2) =>
tag1.name.localeCompare(tag2.name),
);
return {letter, tags: sortedTags};
})
);
}