@docusaurus/plugin-content-blog 3.4.0 → 3.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/atom.css +75 -0
- package/assets/atom.xsl +92 -0
- package/assets/rss.css +75 -0
- package/assets/rss.xsl +86 -0
- package/lib/authors.d.ts +9 -11
- package/lib/authors.js +42 -64
- package/lib/authorsMap.d.ts +23 -0
- package/lib/authorsMap.js +116 -0
- package/lib/authorsProblems.d.ts +21 -0
- package/lib/authorsProblems.js +51 -0
- package/lib/authorsSocials.d.ts +10 -0
- package/lib/authorsSocials.js +48 -0
- package/lib/blogUtils.d.ts +6 -3
- package/lib/blogUtils.js +29 -14
- package/lib/client/contexts.d.ts +33 -0
- package/lib/client/contexts.js +54 -0
- package/lib/client/index.d.ts +3 -3
- package/lib/client/index.js +3 -9
- package/lib/client/sidebarUtils.d.ts +21 -0
- package/lib/client/sidebarUtils.js +49 -0
- package/lib/client/sidebarUtils.test.d.ts +7 -0
- package/lib/client/sidebarUtils.test.js +43 -0
- package/lib/client/structuredDataUtils.d.ts +10 -0
- package/lib/client/structuredDataUtils.js +122 -0
- package/lib/feed.d.ts +3 -2
- package/lib/feed.js +69 -21
- package/lib/frontMatter.d.ts +0 -1
- package/lib/frontMatter.js +3 -2
- package/lib/index.d.ts +0 -1
- package/lib/index.js +23 -4
- package/lib/markdownLoader.js +1 -1
- package/lib/options.d.ts +4 -1
- package/lib/options.js +98 -26
- package/lib/props.d.ts +9 -2
- package/lib/props.js +21 -3
- package/lib/remark/footnoteIDFixer.js +1 -1
- package/lib/routes.d.ts +0 -1
- package/lib/routes.js +82 -14
- package/lib/translations.d.ts +0 -1
- package/lib/translations.js +2 -3
- package/package.json +14 -11
- package/src/authors.ts +56 -93
- package/src/authorsMap.ts +171 -0
- package/src/authorsProblems.ts +72 -0
- package/src/authorsSocials.ts +64 -0
- package/src/blogUtils.ts +34 -7
- package/src/client/contexts.tsx +95 -0
- package/src/client/index.tsx +24 -0
- package/src/client/sidebarUtils.test.ts +52 -0
- package/src/client/sidebarUtils.tsx +85 -0
- package/src/client/structuredDataUtils.ts +178 -0
- package/src/feed.ts +140 -17
- package/src/frontMatter.ts +2 -0
- package/src/index.ts +31 -1
- package/src/options.ts +123 -32
- package/src/plugin-content-blog.d.ts +150 -12
- package/src/props.ts +39 -1
- package/src/routes.ts +102 -12
- package/src/client/index.ts +0 -20
|
@@ -22,13 +22,7 @@ declare module '@docusaurus/plugin-content-blog' {
|
|
|
22
22
|
|
|
23
23
|
export type Assets = {
|
|
24
24
|
/**
|
|
25
|
-
* If `metadata.
|
|
26
|
-
4
|
|
27
|
-
yarn workspace v1.22.19yarn workspace website typecheck
|
|
28
|
-
4
|
|
29
|
-
yarn workspace v1.22.19yarn workspace website typecheck
|
|
30
|
-
4
|
|
31
|
-
yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
|
25
|
+
* If `metadata.image` is a collocated image path, this entry will be the
|
|
32
26
|
* bundler-generated image path. Otherwise, it's empty, and the image URL
|
|
33
27
|
* should be accessed through `frontMatter.image`.
|
|
34
28
|
*/
|
|
@@ -43,7 +37,30 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
|
|
43
37
|
authorsImageUrls: (string | undefined)[];
|
|
44
38
|
};
|
|
45
39
|
|
|
46
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Note we don't pre-define all possible platforms
|
|
42
|
+
* Users can add their own custom platforms if needed
|
|
43
|
+
*/
|
|
44
|
+
export type SocialPlatformKey =
|
|
45
|
+
| 'twitter'
|
|
46
|
+
| 'github'
|
|
47
|
+
| 'linkedin'
|
|
48
|
+
| 'stackoverflow'
|
|
49
|
+
| 'x';
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Social platforms of the author.
|
|
53
|
+
* The record value is usually the fully qualified link of the social profile.
|
|
54
|
+
* For pre-defined platforms, it's possible to pass a handle instead
|
|
55
|
+
*/
|
|
56
|
+
export type AuthorSocials = Partial<Record<SocialPlatformKey, string>> & {
|
|
57
|
+
/**
|
|
58
|
+
* Unknown keys are allowed: users can pass additional social platforms
|
|
59
|
+
*/
|
|
60
|
+
[customAuthorSocialPlatform: string]: string;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type AuthorAttributes = {
|
|
47
64
|
/**
|
|
48
65
|
* If `name` doesn't exist, an `imageURL` is expected.
|
|
49
66
|
*/
|
|
@@ -68,10 +85,48 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
|
|
68
85
|
*/
|
|
69
86
|
email?: string;
|
|
70
87
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
88
|
+
* Social platforms of the author
|
|
89
|
+
* Usually displayed as a list of social icon links.
|
|
90
|
+
*/
|
|
91
|
+
socials?: AuthorSocials;
|
|
92
|
+
/**
|
|
93
|
+
* Description of the author.
|
|
94
|
+
*/
|
|
95
|
+
description?: string;
|
|
96
|
+
/**
|
|
97
|
+
* Unknown keys are allowed, so that we can pass custom fields to authors.
|
|
98
|
+
*/
|
|
99
|
+
[customAuthorAttribute: string]: unknown;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Metadata of the author's page, if it exists.
|
|
104
|
+
*/
|
|
105
|
+
export type AuthorPage = {permalink: string};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Normalized author metadata.
|
|
109
|
+
*/
|
|
110
|
+
export type Author = AuthorAttributes & {
|
|
111
|
+
/**
|
|
112
|
+
* Author key, if the author was loaded from the authors map.
|
|
113
|
+
* `null` means the author was declared inline.
|
|
114
|
+
*/
|
|
115
|
+
key: string | null;
|
|
116
|
+
/**
|
|
117
|
+
* Metadata of the author's page.
|
|
118
|
+
* `null` means the author doesn't have a dedicated author page.
|
|
73
119
|
*/
|
|
74
|
-
|
|
120
|
+
page: AuthorPage | null;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/** Authors coming from the AuthorsMap always have a key */
|
|
124
|
+
export type AuthorWithKey = Author & {key: string};
|
|
125
|
+
|
|
126
|
+
/** What the authors list page should know about each author. */
|
|
127
|
+
export type AuthorItemProp = AuthorWithKey & {
|
|
128
|
+
/** Number of blog posts with this author. */
|
|
129
|
+
count: number;
|
|
75
130
|
};
|
|
76
131
|
|
|
77
132
|
/**
|
|
@@ -165,7 +220,7 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
|
|
165
220
|
last_update?: FrontMatterLastUpdate;
|
|
166
221
|
};
|
|
167
222
|
|
|
168
|
-
export type BlogPostFrontMatterAuthor =
|
|
223
|
+
export type BlogPostFrontMatterAuthor = AuthorAttributes & {
|
|
169
224
|
/**
|
|
170
225
|
* Will be normalized into the `imageURL` prop.
|
|
171
226
|
*/
|
|
@@ -260,10 +315,26 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
|
|
260
315
|
}) => string | undefined;
|
|
261
316
|
|
|
262
317
|
export type FeedType = 'rss' | 'atom' | 'json';
|
|
318
|
+
|
|
319
|
+
export type FeedXSLTOptions = {
|
|
320
|
+
/**
|
|
321
|
+
* RSS XSLT file path, relative to the blog content folder.
|
|
322
|
+
* If null, no XSLT file is used and the feed will be displayed as raw XML.
|
|
323
|
+
*/
|
|
324
|
+
rss: string | null;
|
|
325
|
+
/**
|
|
326
|
+
* Atom XSLT file path, relative to the blog content folder.
|
|
327
|
+
* If null, no XSLT file is used and the feed will be displayed as raw XML.
|
|
328
|
+
*/
|
|
329
|
+
atom: string | null;
|
|
330
|
+
};
|
|
331
|
+
|
|
263
332
|
/**
|
|
264
333
|
* Normalized feed options used within code.
|
|
265
334
|
*/
|
|
266
335
|
export type FeedOptions = {
|
|
336
|
+
/** Enable feeds xslt stylesheets */
|
|
337
|
+
xslt: FeedXSLTOptions;
|
|
267
338
|
/** If `null`, no feed is generated. */
|
|
268
339
|
type?: FeedType[] | null;
|
|
269
340
|
/** Title of generated feed. */
|
|
@@ -398,6 +469,10 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
|
|
398
469
|
blogTagsListComponent: string;
|
|
399
470
|
/** Root component of the "posts containing tag" page. */
|
|
400
471
|
blogTagsPostsComponent: string;
|
|
472
|
+
/** Root component of the authors list page. */
|
|
473
|
+
blogAuthorsListComponent: string;
|
|
474
|
+
/** Root component of the "posts containing author" page. */
|
|
475
|
+
blogAuthorsPostsComponent: string;
|
|
401
476
|
/** Root component of the blog archive page. */
|
|
402
477
|
blogArchiveComponent: string;
|
|
403
478
|
/** Blog page title for better SEO. */
|
|
@@ -442,8 +517,22 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
|
|
442
517
|
* (filter, modify, delete, etc...).
|
|
443
518
|
*/
|
|
444
519
|
processBlogPosts: ProcessBlogPostsFn;
|
|
520
|
+
/* Base path for the authors page */
|
|
521
|
+
authorsBasePath: string;
|
|
522
|
+
/** The behavior of Docusaurus when it finds inline authors. */
|
|
523
|
+
onInlineAuthors: 'ignore' | 'log' | 'warn' | 'throw';
|
|
524
|
+
/** The behavior of Docusaurus when it finds untruncated blog posts. */
|
|
525
|
+
onUntruncatedBlogPosts: 'ignore' | 'log' | 'warn' | 'throw';
|
|
445
526
|
};
|
|
446
527
|
|
|
528
|
+
export type UserFeedXSLTOptions =
|
|
529
|
+
| boolean
|
|
530
|
+
| null
|
|
531
|
+
| {
|
|
532
|
+
rss?: string | boolean | null;
|
|
533
|
+
atom?: string | boolean | null;
|
|
534
|
+
};
|
|
535
|
+
|
|
447
536
|
/**
|
|
448
537
|
* Feed options, as provided by user config. `type` accepts `all` as shortcut
|
|
449
538
|
*/
|
|
@@ -452,6 +541,8 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
|
|
452
541
|
{
|
|
453
542
|
/** Type of feed to be generated. Use `null` to disable generation. */
|
|
454
543
|
type?: FeedOptions['type'] | 'all' | FeedType;
|
|
544
|
+
/** User-provided XSLT config for feeds, un-normalized */
|
|
545
|
+
xslt?: UserFeedXSLTOptions;
|
|
455
546
|
}
|
|
456
547
|
>;
|
|
457
548
|
/**
|
|
@@ -469,6 +560,7 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
|
|
469
560
|
title: string;
|
|
470
561
|
permalink: string;
|
|
471
562
|
unlisted: boolean;
|
|
563
|
+
date: Date | string;
|
|
472
564
|
};
|
|
473
565
|
|
|
474
566
|
export type BlogSidebar = {
|
|
@@ -476,17 +568,22 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
|
|
476
568
|
items: BlogSidebarItem[];
|
|
477
569
|
};
|
|
478
570
|
|
|
571
|
+
export type AuthorsMap = {[authorKey: string]: AuthorWithKey};
|
|
572
|
+
|
|
479
573
|
export type BlogContent = {
|
|
480
574
|
blogSidebarTitle: string;
|
|
481
575
|
blogPosts: BlogPost[];
|
|
482
576
|
blogListPaginated: BlogPaginated[];
|
|
483
577
|
blogTags: BlogTags;
|
|
484
578
|
blogTagsListPath: string;
|
|
579
|
+
authorsMap?: AuthorsMap;
|
|
485
580
|
};
|
|
486
581
|
|
|
487
582
|
export type BlogMetadata = {
|
|
488
583
|
/** the path to the base of the blog */
|
|
489
584
|
blogBasePath: string;
|
|
585
|
+
/** the path to the authors list page */
|
|
586
|
+
authorsListPath: string;
|
|
490
587
|
/** title of the overall blog */
|
|
491
588
|
blogTitle: string;
|
|
492
589
|
};
|
|
@@ -647,6 +744,47 @@ declare module '@theme/BlogTagsListPage' {
|
|
|
647
744
|
export default function BlogTagsListPage(props: Props): JSX.Element;
|
|
648
745
|
}
|
|
649
746
|
|
|
747
|
+
declare module '@theme/Blog/Pages/BlogAuthorsListPage' {
|
|
748
|
+
import type {
|
|
749
|
+
AuthorItemProp,
|
|
750
|
+
BlogSidebar,
|
|
751
|
+
} from '@docusaurus/plugin-content-blog';
|
|
752
|
+
|
|
753
|
+
export interface Props {
|
|
754
|
+
/** Blog sidebar. */
|
|
755
|
+
readonly sidebar: BlogSidebar;
|
|
756
|
+
/** All authors declared in this blog. */
|
|
757
|
+
readonly authors: AuthorItemProp[];
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
export default function BlogAuthorsListPage(props: Props): JSX.Element;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
declare module '@theme/Blog/Pages/BlogAuthorsPostsPage' {
|
|
764
|
+
import type {Content} from '@theme/BlogPostPage';
|
|
765
|
+
import type {
|
|
766
|
+
AuthorItemProp,
|
|
767
|
+
BlogSidebar,
|
|
768
|
+
BlogPaginatedMetadata,
|
|
769
|
+
} from '@docusaurus/plugin-content-blog';
|
|
770
|
+
|
|
771
|
+
export interface Props {
|
|
772
|
+
/** Blog sidebar. */
|
|
773
|
+
readonly sidebar: BlogSidebar;
|
|
774
|
+
/** Metadata of this author. */
|
|
775
|
+
readonly author: AuthorItemProp;
|
|
776
|
+
/** Looks exactly the same as the posts list page */
|
|
777
|
+
readonly listMetadata: BlogPaginatedMetadata;
|
|
778
|
+
/**
|
|
779
|
+
* Array of blog posts included on this page. Every post's metadata is also
|
|
780
|
+
* available.
|
|
781
|
+
*/
|
|
782
|
+
readonly items: readonly {readonly content: Content}[];
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
export default function BlogAuthorsPostsPage(props: Props): JSX.Element;
|
|
786
|
+
}
|
|
787
|
+
|
|
650
788
|
declare module '@theme/BlogTagsPostsPage' {
|
|
651
789
|
import type {Content} from '@theme/BlogPostPage';
|
|
652
790
|
import type {
|
package/src/props.ts
CHANGED
|
@@ -5,7 +5,14 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import type {TagsListItem, TagModule} from '@docusaurus/utils';
|
|
8
|
-
import type {
|
|
8
|
+
import type {
|
|
9
|
+
AuthorItemProp,
|
|
10
|
+
AuthorWithKey,
|
|
11
|
+
BlogPost,
|
|
12
|
+
BlogSidebar,
|
|
13
|
+
BlogTag,
|
|
14
|
+
BlogTags,
|
|
15
|
+
} from '@docusaurus/plugin-content-blog';
|
|
9
16
|
|
|
10
17
|
export function toTagsProp({blogTags}: {blogTags: BlogTags}): TagsListItem[] {
|
|
11
18
|
return Object.values(blogTags)
|
|
@@ -34,3 +41,34 @@ export function toTagProp({
|
|
|
34
41
|
unlisted: tag.unlisted,
|
|
35
42
|
};
|
|
36
43
|
}
|
|
44
|
+
|
|
45
|
+
export function toAuthorItemProp({
|
|
46
|
+
author,
|
|
47
|
+
count,
|
|
48
|
+
}: {
|
|
49
|
+
author: AuthorWithKey;
|
|
50
|
+
count: number;
|
|
51
|
+
}): AuthorItemProp {
|
|
52
|
+
return {
|
|
53
|
+
...author,
|
|
54
|
+
count,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function toBlogSidebarProp({
|
|
59
|
+
blogSidebarTitle,
|
|
60
|
+
blogPosts,
|
|
61
|
+
}: {
|
|
62
|
+
blogSidebarTitle: string;
|
|
63
|
+
blogPosts: BlogPost[];
|
|
64
|
+
}): BlogSidebar {
|
|
65
|
+
return {
|
|
66
|
+
title: blogSidebarTitle,
|
|
67
|
+
items: blogPosts.map((blogPost) => ({
|
|
68
|
+
title: blogPost.metadata.title,
|
|
69
|
+
permalink: blogPost.metadata.permalink,
|
|
70
|
+
unlisted: blogPost.metadata.unlisted,
|
|
71
|
+
date: blogPost.metadata.date,
|
|
72
|
+
})),
|
|
73
|
+
};
|
|
74
|
+
}
|
package/src/routes.ts
CHANGED
|
@@ -11,9 +11,15 @@ import {
|
|
|
11
11
|
docuHash,
|
|
12
12
|
aliasedSitePathToRelativePath,
|
|
13
13
|
} from '@docusaurus/utils';
|
|
14
|
-
import {shouldBeListed} from './blogUtils';
|
|
14
|
+
import {paginateBlogPosts, shouldBeListed} from './blogUtils';
|
|
15
15
|
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
toAuthorItemProp,
|
|
18
|
+
toBlogSidebarProp,
|
|
19
|
+
toTagProp,
|
|
20
|
+
toTagsProp,
|
|
21
|
+
} from './props';
|
|
22
|
+
import {groupBlogPostsByAuthorKey} from './authors';
|
|
17
23
|
import type {
|
|
18
24
|
PluginContentLoadedActions,
|
|
19
25
|
RouteConfig,
|
|
@@ -26,7 +32,7 @@ import type {
|
|
|
26
32
|
BlogContent,
|
|
27
33
|
PluginOptions,
|
|
28
34
|
BlogPost,
|
|
29
|
-
|
|
35
|
+
AuthorWithKey,
|
|
30
36
|
} from '@docusaurus/plugin-content-blog';
|
|
31
37
|
|
|
32
38
|
type CreateAllRoutesParam = {
|
|
@@ -55,11 +61,16 @@ export async function buildAllRoutes({
|
|
|
55
61
|
blogListComponent,
|
|
56
62
|
blogPostComponent,
|
|
57
63
|
blogTagsListComponent,
|
|
64
|
+
blogAuthorsListComponent,
|
|
65
|
+
blogAuthorsPostsComponent,
|
|
58
66
|
blogTagsPostsComponent,
|
|
59
67
|
blogArchiveComponent,
|
|
60
68
|
routeBasePath,
|
|
61
69
|
archiveBasePath,
|
|
62
70
|
blogTitle,
|
|
71
|
+
authorsBasePath,
|
|
72
|
+
postsPerPage,
|
|
73
|
+
blogDescription,
|
|
63
74
|
} = options;
|
|
64
75
|
const pluginId = options.id!;
|
|
65
76
|
const {createData} = actions;
|
|
@@ -69,8 +80,15 @@ export async function buildAllRoutes({
|
|
|
69
80
|
blogListPaginated,
|
|
70
81
|
blogTags,
|
|
71
82
|
blogTagsListPath,
|
|
83
|
+
authorsMap,
|
|
72
84
|
} = content;
|
|
73
85
|
|
|
86
|
+
const authorsListPath = normalizeUrl([
|
|
87
|
+
baseUrl,
|
|
88
|
+
routeBasePath,
|
|
89
|
+
authorsBasePath,
|
|
90
|
+
]);
|
|
91
|
+
|
|
74
92
|
const listedBlogPosts = blogPosts.filter(shouldBeListed);
|
|
75
93
|
|
|
76
94
|
const blogPostsById = _.keyBy(blogPosts, (post) => post.id);
|
|
@@ -88,17 +106,13 @@ export async function buildAllRoutes({
|
|
|
88
106
|
: blogPosts.slice(0, options.blogSidebarCount);
|
|
89
107
|
|
|
90
108
|
async function createSidebarModule() {
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
permalink: blogPost.metadata.permalink,
|
|
96
|
-
unlisted: blogPost.metadata.unlisted,
|
|
97
|
-
})),
|
|
98
|
-
};
|
|
109
|
+
const sidebarProp = toBlogSidebarProp({
|
|
110
|
+
blogSidebarTitle,
|
|
111
|
+
blogPosts: sidebarBlogPosts,
|
|
112
|
+
});
|
|
99
113
|
const modulePath = await createData(
|
|
100
114
|
`blog-post-list-prop-${pluginId}.json`,
|
|
101
|
-
|
|
115
|
+
sidebarProp,
|
|
102
116
|
);
|
|
103
117
|
return aliasedSource(modulePath);
|
|
104
118
|
}
|
|
@@ -107,6 +121,7 @@ export async function buildAllRoutes({
|
|
|
107
121
|
const blogMetadata: BlogMetadata = {
|
|
108
122
|
blogBasePath: normalizeUrl([baseUrl, routeBasePath]),
|
|
109
123
|
blogTitle,
|
|
124
|
+
authorsListPath,
|
|
110
125
|
};
|
|
111
126
|
const modulePath = await createData(
|
|
112
127
|
`blogMetadata-${pluginId}.json`,
|
|
@@ -254,10 +269,85 @@ export async function buildAllRoutes({
|
|
|
254
269
|
return [tagsListRoute, ...tagsPaginatedRoutes];
|
|
255
270
|
}
|
|
256
271
|
|
|
272
|
+
function createAuthorsRoutes(): RouteConfig[] {
|
|
273
|
+
if (authorsMap === undefined || Object.keys(authorsMap).length === 0) {
|
|
274
|
+
return [];
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const blogPostsByAuthorKey = groupBlogPostsByAuthorKey({
|
|
278
|
+
authorsMap,
|
|
279
|
+
blogPosts,
|
|
280
|
+
});
|
|
281
|
+
const authors = Object.values(authorsMap);
|
|
282
|
+
|
|
283
|
+
return [
|
|
284
|
+
createAuthorListRoute(),
|
|
285
|
+
...authors.flatMap(createAuthorPaginatedRoute),
|
|
286
|
+
];
|
|
287
|
+
|
|
288
|
+
function createAuthorListRoute(): RouteConfig {
|
|
289
|
+
return {
|
|
290
|
+
path: authorsListPath,
|
|
291
|
+
component: blogAuthorsListComponent,
|
|
292
|
+
exact: true,
|
|
293
|
+
modules: {
|
|
294
|
+
sidebar: sidebarModulePath,
|
|
295
|
+
},
|
|
296
|
+
props: {
|
|
297
|
+
authors: authors.map((author) =>
|
|
298
|
+
toAuthorItemProp({
|
|
299
|
+
author,
|
|
300
|
+
count: blogPostsByAuthorKey[author.key]?.length ?? 0,
|
|
301
|
+
}),
|
|
302
|
+
),
|
|
303
|
+
},
|
|
304
|
+
context: {
|
|
305
|
+
blogMetadata: blogMetadataModulePath,
|
|
306
|
+
},
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function createAuthorPaginatedRoute(author: AuthorWithKey): RouteConfig[] {
|
|
311
|
+
const authorBlogPosts = blogPostsByAuthorKey[author.key] ?? [];
|
|
312
|
+
if (!author.page) {
|
|
313
|
+
return [];
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const pages = paginateBlogPosts({
|
|
317
|
+
blogPosts: authorBlogPosts,
|
|
318
|
+
basePageUrl: author.page.permalink,
|
|
319
|
+
blogDescription,
|
|
320
|
+
blogTitle,
|
|
321
|
+
pageBasePath: authorsBasePath,
|
|
322
|
+
postsPerPageOption: postsPerPage,
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
return pages.map(({metadata, items}) => {
|
|
326
|
+
return {
|
|
327
|
+
path: metadata.permalink,
|
|
328
|
+
component: blogAuthorsPostsComponent,
|
|
329
|
+
exact: true,
|
|
330
|
+
modules: {
|
|
331
|
+
items: blogPostItemsModule(items),
|
|
332
|
+
sidebar: sidebarModulePath,
|
|
333
|
+
},
|
|
334
|
+
props: {
|
|
335
|
+
author: toAuthorItemProp({author, count: authorBlogPosts.length}),
|
|
336
|
+
listMetadata: metadata,
|
|
337
|
+
},
|
|
338
|
+
context: {
|
|
339
|
+
blogMetadata: blogMetadataModulePath,
|
|
340
|
+
},
|
|
341
|
+
};
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
257
346
|
return [
|
|
258
347
|
...createBlogPostRoutes(),
|
|
259
348
|
...createBlogPostsPaginatedRoutes(),
|
|
260
349
|
...createTagsRoutes(),
|
|
261
350
|
...createArchiveRoute(),
|
|
351
|
+
...createAuthorsRoutes(),
|
|
262
352
|
];
|
|
263
353
|
}
|
package/src/client/index.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import useRouteContext from '@docusaurus/useRouteContext';
|
|
9
|
-
import type {BlogMetadata} from '@docusaurus/plugin-content-blog';
|
|
10
|
-
|
|
11
|
-
export function useBlogMetadata(): BlogMetadata {
|
|
12
|
-
const routeContext = useRouteContext();
|
|
13
|
-
const blogMetadata = routeContext?.data?.blogMetadata;
|
|
14
|
-
if (!blogMetadata) {
|
|
15
|
-
throw new Error(
|
|
16
|
-
"useBlogMetadata() can't be called on the current route because the blog metadata could not be found in route context",
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
return blogMetadata as BlogMetadata;
|
|
20
|
-
}
|