mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-21 21:16:59 +02:00
refactor(content-{blog,docs}): unify handling of tags (#7117)
This commit is contained in:
parent
ca718ccac0
commit
1156be3f20
24 changed files with 170 additions and 178 deletions
|
@ -8,7 +8,7 @@ exports[`blog plugin works on blog tags without pagination 1`] = `
|
|||
"/another/tags",
|
||||
"/another/tags2",
|
||||
],
|
||||
"name": "tag1",
|
||||
"label": "tag1",
|
||||
"pages": [
|
||||
{
|
||||
"items": [
|
||||
|
@ -36,7 +36,7 @@ exports[`blog plugin works on blog tags without pagination 1`] = `
|
|||
"/another/tags",
|
||||
"/another/tags2",
|
||||
],
|
||||
"name": "tag2",
|
||||
"label": "tag2",
|
||||
"pages": [
|
||||
{
|
||||
"items": [
|
||||
|
@ -69,7 +69,7 @@ exports[`blog plugin works with blog tags 1`] = `
|
|||
"/another/tags",
|
||||
"/another/tags2",
|
||||
],
|
||||
"name": "tag1",
|
||||
"label": "tag1",
|
||||
"pages": [
|
||||
{
|
||||
"items": [
|
||||
|
@ -112,7 +112,7 @@ exports[`blog plugin works with blog tags 1`] = `
|
|||
"/another/tags",
|
||||
"/another/tags2",
|
||||
],
|
||||
"name": "tag2",
|
||||
"label": "tag2",
|
||||
"pages": [
|
||||
{
|
||||
"items": [
|
||||
|
|
|
@ -114,7 +114,7 @@ export function getBlogTags({
|
|||
);
|
||||
|
||||
return _.mapValues(groups, ({tag, items: tagBlogPosts}) => ({
|
||||
name: tag.label,
|
||||
label: tag.label,
|
||||
items: tagBlogPosts.map((item) => item.id),
|
||||
permalink: tag.permalink,
|
||||
pages: paginateBlogPosts({
|
||||
|
|
|
@ -30,7 +30,13 @@ import type {
|
|||
BlogContentPaths,
|
||||
BlogMarkdownLoaderOptions,
|
||||
} from './types';
|
||||
import type {LoadContext, Plugin, HtmlTags} from '@docusaurus/types';
|
||||
import type {
|
||||
LoadContext,
|
||||
Plugin,
|
||||
HtmlTags,
|
||||
TagsListItem,
|
||||
TagModule,
|
||||
} from '@docusaurus/types';
|
||||
import {
|
||||
generateBlogPosts,
|
||||
getSourceToPermalink,
|
||||
|
@ -43,7 +49,6 @@ import type {
|
|||
BlogPostFrontMatter,
|
||||
BlogPostMetadata,
|
||||
Assets,
|
||||
TagModule,
|
||||
} from '@docusaurus/plugin-content-blog';
|
||||
|
||||
export default async function pluginContentBlog(
|
||||
|
@ -117,6 +122,8 @@ export default async function pluginContentBlog(
|
|||
blogSidebarTitle,
|
||||
} = options;
|
||||
|
||||
const baseBlogUrl = normalizeUrl([baseUrl, routeBasePath]);
|
||||
const blogTagsListPath = normalizeUrl([baseBlogUrl, tagsBasePath]);
|
||||
const blogPosts = await generateBlogPosts(contentPaths, context, options);
|
||||
|
||||
if (!blogPosts.length) {
|
||||
|
@ -125,7 +132,7 @@ export default async function pluginContentBlog(
|
|||
blogPosts: [],
|
||||
blogListPaginated: [],
|
||||
blogTags: {},
|
||||
blogTagsListPath: null,
|
||||
blogTagsListPath,
|
||||
blogTagsPaginated: [],
|
||||
};
|
||||
}
|
||||
|
@ -150,8 +157,6 @@ export default async function pluginContentBlog(
|
|||
}
|
||||
});
|
||||
|
||||
const baseBlogUrl = normalizeUrl([baseUrl, routeBasePath]);
|
||||
|
||||
const blogListPaginated: BlogPaginated[] = paginateBlogPosts({
|
||||
blogPosts,
|
||||
blogTitle,
|
||||
|
@ -167,11 +172,6 @@ export default async function pluginContentBlog(
|
|||
blogTitle,
|
||||
});
|
||||
|
||||
const tagsPath = normalizeUrl([baseBlogUrl, tagsBasePath]);
|
||||
|
||||
const blogTagsListPath =
|
||||
Object.keys(blogTags).length > 0 ? tagsPath : null;
|
||||
|
||||
return {
|
||||
blogSidebarTitle,
|
||||
blogPosts,
|
||||
|
@ -307,30 +307,47 @@ export default async function pluginContentBlog(
|
|||
}),
|
||||
);
|
||||
|
||||
// Tags.
|
||||
if (blogTagsListPath === null) {
|
||||
// Tags. This is the last part so we early-return if there are no tags.
|
||||
if (Object.keys(blogTags).length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tagsModule: {[tagName: string]: TagModule} = Object.fromEntries(
|
||||
Object.entries(blogTags).map(([, tag]) => {
|
||||
const tagModule: TagModule = {
|
||||
allTagsPath: blogTagsListPath,
|
||||
name: tag.name,
|
||||
count: tag.items.length,
|
||||
permalink: tag.permalink,
|
||||
};
|
||||
return [tag.name, tagModule];
|
||||
}),
|
||||
);
|
||||
async function createTagsListPage() {
|
||||
const tagsProp: TagsListItem[] = Object.values(blogTags).map((tag) => ({
|
||||
label: tag.label,
|
||||
permalink: tag.permalink,
|
||||
count: tag.items.length,
|
||||
}));
|
||||
|
||||
async function createTagRoutes(tag: BlogTag): Promise<void> {
|
||||
const tagsPropPath = await createData(
|
||||
`${docuHash(`${blogTagsListPath}-tags`)}.json`,
|
||||
JSON.stringify(tagsProp, null, 2),
|
||||
);
|
||||
|
||||
addRoute({
|
||||
path: blogTagsListPath,
|
||||
component: blogTagsListComponent,
|
||||
exact: true,
|
||||
modules: {
|
||||
sidebar: aliasedSource(sidebarProp),
|
||||
tags: aliasedSource(tagsPropPath),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function createTagPostsListPage(tag: BlogTag): Promise<void> {
|
||||
await Promise.all(
|
||||
tag.pages.map(async (blogPaginated) => {
|
||||
const {metadata, items} = blogPaginated;
|
||||
const tagsMetadataPath = await createData(
|
||||
const tagProp: TagModule = {
|
||||
label: tag.label,
|
||||
permalink: tag.permalink,
|
||||
allTagsPath: blogTagsListPath,
|
||||
count: tag.items.length,
|
||||
};
|
||||
const tagPropPath = await createData(
|
||||
`${docuHash(metadata.permalink)}.json`,
|
||||
JSON.stringify(tagsModule[tag.name], null, 2),
|
||||
JSON.stringify(tagProp, null, 2),
|
||||
);
|
||||
|
||||
const listMetadataPath = await createData(
|
||||
|
@ -356,7 +373,7 @@ export default async function pluginContentBlog(
|
|||
},
|
||||
};
|
||||
}),
|
||||
metadata: aliasedSource(tagsMetadataPath),
|
||||
tag: aliasedSource(tagPropPath),
|
||||
listMetadata: aliasedSource(listMetadataPath),
|
||||
},
|
||||
});
|
||||
|
@ -364,25 +381,8 @@ export default async function pluginContentBlog(
|
|||
);
|
||||
}
|
||||
|
||||
await Promise.all(Object.values(blogTags).map(createTagRoutes));
|
||||
|
||||
// Only create /tags page if there are tags.
|
||||
if (Object.keys(blogTags).length > 0) {
|
||||
const tagsListPath = await createData(
|
||||
`${docuHash(`${blogTagsListPath}-tags`)}.json`,
|
||||
JSON.stringify(tagsModule, null, 2),
|
||||
);
|
||||
|
||||
addRoute({
|
||||
path: blogTagsListPath,
|
||||
component: blogTagsListComponent,
|
||||
exact: true,
|
||||
modules: {
|
||||
sidebar: aliasedSource(sidebarProp),
|
||||
tags: aliasedSource(tagsListPath),
|
||||
},
|
||||
});
|
||||
}
|
||||
await createTagsListPage();
|
||||
await Promise.all(Object.values(blogTags).map(createTagPostsListPage));
|
||||
},
|
||||
|
||||
translateContent({content, translationFiles}) {
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
|
||||
declare module '@docusaurus/plugin-content-blog' {
|
||||
import type {MDXOptions} from '@docusaurus/mdx-loader';
|
||||
import type {FrontMatterTag, Tag} from '@docusaurus/utils';
|
||||
import type {FrontMatterTag} from '@docusaurus/utils';
|
||||
import type {Overwrite} from 'utility-types';
|
||||
import type {Tag} from '@docusaurus/types';
|
||||
|
||||
export type Assets = {
|
||||
/**
|
||||
|
@ -406,17 +407,6 @@ declare module '@docusaurus/plugin-content-blog' {
|
|||
}
|
||||
>;
|
||||
|
||||
export type TagModule = {
|
||||
/** Permalink of the tag's own page. */
|
||||
permalink: string;
|
||||
/** Name of the tag. */
|
||||
name: string;
|
||||
/** Number of posts with this tag. */
|
||||
count: number;
|
||||
/** The tags list page. */
|
||||
allTagsPath: string;
|
||||
};
|
||||
|
||||
export type BlogSidebar = {
|
||||
title: string;
|
||||
items: {title: string; permalink: string}[];
|
||||
|
@ -511,28 +501,30 @@ declare module '@theme/BlogListPage' {
|
|||
}
|
||||
|
||||
declare module '@theme/BlogTagsListPage' {
|
||||
import type {BlogSidebar, TagModule} from '@docusaurus/plugin-content-blog';
|
||||
import type {BlogSidebar} from '@docusaurus/plugin-content-blog';
|
||||
import type {TagsListItem} from '@docusaurus/types';
|
||||
|
||||
export interface Props {
|
||||
/** Blog sidebar. */
|
||||
readonly sidebar: BlogSidebar;
|
||||
/** A map from tag names to the full tag module. */
|
||||
readonly tags: Readonly<{[tagName: string]: TagModule}>;
|
||||
/** All tags declared in this blog. */
|
||||
readonly tags: TagsListItem[];
|
||||
}
|
||||
|
||||
export default function BlogTagsListPage(props: Props): JSX.Element;
|
||||
}
|
||||
|
||||
declare module '@theme/BlogTagsPostsPage' {
|
||||
import type {BlogSidebar, TagModule} from '@docusaurus/plugin-content-blog';
|
||||
import type {BlogSidebar} from '@docusaurus/plugin-content-blog';
|
||||
import type {Content} from '@theme/BlogPostPage';
|
||||
import type {Metadata} from '@theme/BlogListPage';
|
||||
import type {TagModule} from '@docusaurus/types';
|
||||
|
||||
export interface Props {
|
||||
/** Blog sidebar. */
|
||||
readonly sidebar: BlogSidebar;
|
||||
/** Metadata of this tag. */
|
||||
readonly metadata: TagModule;
|
||||
readonly tag: TagModule;
|
||||
/** Looks exactly the same as the posts list page */
|
||||
readonly listMetadata: Metadata;
|
||||
/**
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import type {BrokenMarkdownLink, ContentPaths} from '@docusaurus/utils';
|
||||
import type {Tag} from '@docusaurus/types';
|
||||
import type {BlogPostMetadata} from '@docusaurus/plugin-content-blog';
|
||||
import type {Metadata as BlogPaginatedMetadata} from '@theme/BlogListPage';
|
||||
|
||||
|
@ -16,22 +17,16 @@ export type BlogContent = {
|
|||
blogPosts: BlogPost[];
|
||||
blogListPaginated: BlogPaginated[];
|
||||
blogTags: BlogTags;
|
||||
blogTagsListPath: string | null;
|
||||
blogTagsListPath: string;
|
||||
};
|
||||
|
||||
export type BlogTags = {
|
||||
// TODO, the key is the tag slug/permalink
|
||||
// This is due to legacy frontmatter: tags:
|
||||
// [{label: "xyz", permalink: "/1"}, {label: "xyz", permalink: "/2"}]
|
||||
// Soon we should forbid declaring permalink through frontmatter
|
||||
[tagKey: string]: BlogTag;
|
||||
[permalink: string]: BlogTag;
|
||||
};
|
||||
|
||||
export type BlogTag = {
|
||||
name: string;
|
||||
export type BlogTag = Tag & {
|
||||
/** Blog post permalinks. */
|
||||
items: string[];
|
||||
permalink: string;
|
||||
pages: BlogPaginated[];
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue