@docusaurus/plugin-content-blog 2.0.0-beta.15a2b59f9 → 2.0.0-beta.17
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/lib/authors.d.ts +20 -0
- package/lib/authors.js +110 -0
- package/lib/blogFrontMatter.d.ts +1 -21
- package/lib/blogFrontMatter.js +31 -19
- package/lib/blogUtils.d.ts +24 -6
- package/lib/blogUtils.js +196 -143
- package/lib/feed.d.ts +15 -0
- package/lib/feed.js +99 -0
- package/lib/index.d.ts +4 -3
- package/lib/index.js +149 -163
- package/lib/markdownLoader.d.ts +3 -6
- package/lib/markdownLoader.js +5 -6
- package/lib/pluginOptionSchema.d.ts +3 -26
- package/lib/pluginOptionSchema.js +35 -10
- package/lib/translations.d.ts +11 -0
- package/lib/translations.js +53 -0
- package/lib/types.d.ts +10 -46
- package/package.json +21 -18
- package/src/authors.ts +153 -0
- package/src/blogFrontMatter.ts +44 -51
- package/src/blogUtils.ts +289 -195
- package/{types.d.ts → src/deps.d.ts} +0 -0
- package/src/feed.ts +170 -0
- package/src/index.ts +197 -194
- package/src/markdownLoader.ts +10 -15
- package/src/plugin-content-blog.d.ts +270 -0
- package/src/pluginOptionSchema.ts +41 -13
- package/src/translations.ts +64 -0
- package/src/types.ts +19 -53
- package/index.d.ts +0 -138
- package/lib/.tsbuildinfo +0 -1
- package/src/__tests__/__fixtures__/website/blog/2018-12-14-Happy-First-Birthday-Slash.md +0 -5
- package/src/__tests__/__fixtures__/website/blog/complex-slug.md +0 -7
- package/src/__tests__/__fixtures__/website/blog/date-matter.md +0 -5
- package/src/__tests__/__fixtures__/website/blog/draft.md +0 -6
- package/src/__tests__/__fixtures__/website/blog/heading-as-title.md +0 -5
- package/src/__tests__/__fixtures__/website/blog/simple-slug.md +0 -7
- package/src/__tests__/__fixtures__/website/blog-with-ref/2018-12-14-Happy-First-Birthday-Slash.md +0 -5
- package/src/__tests__/__fixtures__/website/blog-with-ref/post-with-broken-links.md +0 -11
- package/src/__tests__/__fixtures__/website/blog-with-ref/post.md +0 -5
- package/src/__tests__/__fixtures__/website/i18n/en/docusaurus-plugin-content-blog/2018-12-14-Happy-First-Birthday-Slash.md +0 -5
- package/src/__tests__/__fixtures__/website-blog-without-date/blog/no date.md +0 -1
- package/src/__tests__/__snapshots__/generateBlogFeed.test.ts.snap +0 -76
- package/src/__tests__/__snapshots__/linkify.test.ts.snap +0 -24
- package/src/__tests__/__snapshots__/pluginOptionSchema.test.ts.snap +0 -5
- package/src/__tests__/blogFrontMatter.test.ts +0 -317
- package/src/__tests__/generateBlogFeed.test.ts +0 -100
- package/src/__tests__/index.test.ts +0 -336
- package/src/__tests__/linkify.test.ts +0 -93
- package/src/__tests__/pluginOptionSchema.test.ts +0 -150
- package/tsconfig.json +0 -9
|
@@ -0,0 +1,270 @@
|
|
|
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
|
+
declare module '@docusaurus/plugin-content-blog' {
|
|
9
|
+
import type {RemarkAndRehypePluginOptions} from '@docusaurus/mdx-loader';
|
|
10
|
+
import type {FrontMatterTag} from '@docusaurus/utils';
|
|
11
|
+
import type {Overwrite} from 'utility-types';
|
|
12
|
+
|
|
13
|
+
export interface Assets {
|
|
14
|
+
image?: string;
|
|
15
|
+
authorsImageUrls: (string | undefined)[]; // Array of same size as the original MetaData.authors array
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// We allow passing custom fields to authors, e.g., twitter
|
|
19
|
+
export interface Author extends Record<string, unknown> {
|
|
20
|
+
name?: string;
|
|
21
|
+
imageURL?: string;
|
|
22
|
+
url?: string;
|
|
23
|
+
title?: string;
|
|
24
|
+
email?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type BlogPostFrontMatter = {
|
|
28
|
+
id?: string;
|
|
29
|
+
title?: string;
|
|
30
|
+
description?: string;
|
|
31
|
+
tags?: FrontMatterTag[];
|
|
32
|
+
slug?: string;
|
|
33
|
+
draft?: boolean;
|
|
34
|
+
date?: Date | string; // Yaml automatically convert some string patterns as Date, but not all
|
|
35
|
+
|
|
36
|
+
authors?: BlogPostFrontMatterAuthors;
|
|
37
|
+
|
|
38
|
+
// We may want to deprecate those older author front matter fields later:
|
|
39
|
+
author?: string;
|
|
40
|
+
author_title?: string;
|
|
41
|
+
author_url?: string;
|
|
42
|
+
author_image_url?: string;
|
|
43
|
+
|
|
44
|
+
/** @deprecated */
|
|
45
|
+
authorTitle?: string;
|
|
46
|
+
/** @deprecated */
|
|
47
|
+
authorURL?: string;
|
|
48
|
+
/** @deprecated */
|
|
49
|
+
authorImageURL?: string;
|
|
50
|
+
|
|
51
|
+
image?: string;
|
|
52
|
+
keywords?: string[];
|
|
53
|
+
hide_table_of_contents?: boolean;
|
|
54
|
+
toc_min_heading_level?: number;
|
|
55
|
+
toc_max_heading_level?: number;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export type BlogPostFrontMatterAuthor = Record<string, unknown> & {
|
|
59
|
+
key?: string;
|
|
60
|
+
name?: string;
|
|
61
|
+
imageURL?: string;
|
|
62
|
+
url?: string;
|
|
63
|
+
title?: string;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// All the possible variants that the user can use for convenience
|
|
67
|
+
export type BlogPostFrontMatterAuthors =
|
|
68
|
+
| string
|
|
69
|
+
| BlogPostFrontMatterAuthor
|
|
70
|
+
| (string | BlogPostFrontMatterAuthor)[];
|
|
71
|
+
|
|
72
|
+
export type EditUrlFunction = (editUrlParams: {
|
|
73
|
+
blogDirPath: string;
|
|
74
|
+
blogPath: string;
|
|
75
|
+
permalink: string;
|
|
76
|
+
locale: string;
|
|
77
|
+
}) => string | undefined;
|
|
78
|
+
|
|
79
|
+
export type FeedType = 'rss' | 'atom' | 'json';
|
|
80
|
+
export type FeedOptions = {
|
|
81
|
+
type?: FeedType[] | null;
|
|
82
|
+
title?: string;
|
|
83
|
+
description?: string;
|
|
84
|
+
copyright: string;
|
|
85
|
+
language?: string;
|
|
86
|
+
};
|
|
87
|
+
// Feed options, as provided by user config
|
|
88
|
+
export type UserFeedOptions = Overwrite<
|
|
89
|
+
Partial<FeedOptions>,
|
|
90
|
+
{type?: FeedOptions['type'] | 'all'} // Handle the type: "all" shortcut
|
|
91
|
+
>;
|
|
92
|
+
|
|
93
|
+
// Duplicate from ngryman/reading-time to keep stability of API
|
|
94
|
+
type ReadingTimeOptions = {
|
|
95
|
+
wordsPerMinute?: number;
|
|
96
|
+
wordBound?: (char: string) => boolean;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export type ReadingTimeFunction = (params: {
|
|
100
|
+
content: string;
|
|
101
|
+
frontMatter?: BlogPostFrontMatter & Record<string, unknown>;
|
|
102
|
+
options?: ReadingTimeOptions;
|
|
103
|
+
}) => number;
|
|
104
|
+
|
|
105
|
+
export type ReadingTimeFunctionOption = (
|
|
106
|
+
params: Required<Omit<Parameters<ReadingTimeFunction>[0], 'options'>> & {
|
|
107
|
+
defaultReadingTime: ReadingTimeFunction;
|
|
108
|
+
},
|
|
109
|
+
) => number | undefined;
|
|
110
|
+
|
|
111
|
+
export type PluginOptions = RemarkAndRehypePluginOptions & {
|
|
112
|
+
id?: string;
|
|
113
|
+
path: string;
|
|
114
|
+
routeBasePath: string;
|
|
115
|
+
tagsBasePath: string;
|
|
116
|
+
archiveBasePath: string | null;
|
|
117
|
+
include: string[];
|
|
118
|
+
exclude: string[];
|
|
119
|
+
postsPerPage: number | 'ALL';
|
|
120
|
+
blogListComponent: string;
|
|
121
|
+
blogPostComponent: string;
|
|
122
|
+
blogTagsListComponent: string;
|
|
123
|
+
blogTagsPostsComponent: string;
|
|
124
|
+
blogArchiveComponent: string;
|
|
125
|
+
blogTitle: string;
|
|
126
|
+
blogDescription: string;
|
|
127
|
+
blogSidebarCount: number | 'ALL';
|
|
128
|
+
blogSidebarTitle: string;
|
|
129
|
+
truncateMarker: RegExp;
|
|
130
|
+
showReadingTime: boolean;
|
|
131
|
+
feedOptions: {
|
|
132
|
+
type?: FeedType[] | null;
|
|
133
|
+
title?: string;
|
|
134
|
+
description?: string;
|
|
135
|
+
copyright: string;
|
|
136
|
+
language?: string;
|
|
137
|
+
};
|
|
138
|
+
editUrl?: string | EditUrlFunction;
|
|
139
|
+
editLocalizedFiles?: boolean;
|
|
140
|
+
admonitions: Record<string, unknown>;
|
|
141
|
+
authorsMapPath: string;
|
|
142
|
+
readingTime: ReadingTimeFunctionOption;
|
|
143
|
+
sortPosts: 'ascending' | 'descending';
|
|
144
|
+
};
|
|
145
|
+
// Options, as provided in the user config (before normalization)
|
|
146
|
+
export type Options = Overwrite<
|
|
147
|
+
Partial<PluginOptions>,
|
|
148
|
+
{feedOptions?: UserFeedOptions}
|
|
149
|
+
>;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
declare module '@theme/BlogPostPage' {
|
|
153
|
+
import type {BlogSidebar} from '@theme/BlogSidebar';
|
|
154
|
+
import type {TOCItem} from '@docusaurus/types';
|
|
155
|
+
import type {
|
|
156
|
+
BlogPostFrontMatter,
|
|
157
|
+
Author,
|
|
158
|
+
Assets,
|
|
159
|
+
} from '@docusaurus/plugin-content-blog';
|
|
160
|
+
|
|
161
|
+
export type FrontMatter = BlogPostFrontMatter;
|
|
162
|
+
|
|
163
|
+
export type Metadata = {
|
|
164
|
+
readonly title: string;
|
|
165
|
+
readonly date: string;
|
|
166
|
+
readonly formattedDate: string;
|
|
167
|
+
readonly permalink: string;
|
|
168
|
+
readonly description?: string;
|
|
169
|
+
readonly editUrl?: string;
|
|
170
|
+
readonly readingTime?: number;
|
|
171
|
+
readonly truncated?: string;
|
|
172
|
+
readonly nextItem?: {readonly title: string; readonly permalink: string};
|
|
173
|
+
readonly prevItem?: {readonly title: string; readonly permalink: string};
|
|
174
|
+
readonly authors: Author[];
|
|
175
|
+
readonly frontMatter: FrontMatter & Record<string, unknown>;
|
|
176
|
+
readonly tags: readonly {
|
|
177
|
+
readonly label: string;
|
|
178
|
+
readonly permalink: string;
|
|
179
|
+
}[];
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
export type Content = {
|
|
183
|
+
readonly frontMatter: FrontMatter;
|
|
184
|
+
readonly assets: Assets;
|
|
185
|
+
readonly metadata: Metadata;
|
|
186
|
+
readonly toc: readonly TOCItem[];
|
|
187
|
+
(): JSX.Element;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
export interface Props {
|
|
191
|
+
readonly sidebar: BlogSidebar;
|
|
192
|
+
readonly content: Content;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export default function BlogPostPage(props: Props): JSX.Element;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
declare module '@theme/BlogListPage' {
|
|
199
|
+
import type {Content} from '@theme/BlogPostPage';
|
|
200
|
+
import type {BlogSidebar} from '@theme/BlogSidebar';
|
|
201
|
+
|
|
202
|
+
export type Metadata = {
|
|
203
|
+
readonly blogTitle: string;
|
|
204
|
+
readonly blogDescription: string;
|
|
205
|
+
readonly nextPage?: string;
|
|
206
|
+
readonly page: number;
|
|
207
|
+
readonly permalink: string;
|
|
208
|
+
readonly postsPerPage: number;
|
|
209
|
+
readonly previousPage?: string;
|
|
210
|
+
readonly totalCount: number;
|
|
211
|
+
readonly totalPages: number;
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
export interface Props {
|
|
215
|
+
readonly sidebar: BlogSidebar;
|
|
216
|
+
readonly metadata: Metadata;
|
|
217
|
+
readonly items: readonly {readonly content: Content}[];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export default function BlogListPage(props: Props): JSX.Element;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
declare module '@theme/BlogTagsListPage' {
|
|
224
|
+
import type {BlogSidebar} from '@theme/BlogSidebar';
|
|
225
|
+
|
|
226
|
+
export type Tag = {
|
|
227
|
+
permalink: string;
|
|
228
|
+
name: string;
|
|
229
|
+
count: number;
|
|
230
|
+
allTagsPath: string;
|
|
231
|
+
slug: string;
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
export interface Props {
|
|
235
|
+
readonly sidebar: BlogSidebar;
|
|
236
|
+
readonly tags: Readonly<Record<string, Tag>>;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export default function BlogTagsListPage(props: Props): JSX.Element;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
declare module '@theme/BlogTagsPostsPage' {
|
|
243
|
+
import type {BlogSidebar} from '@theme/BlogSidebar';
|
|
244
|
+
import type {Tag} from '@theme/BlogTagsListPage';
|
|
245
|
+
import type {Content} from '@theme/BlogPostPage';
|
|
246
|
+
import type {Metadata} from '@theme/BlogListPage';
|
|
247
|
+
|
|
248
|
+
export interface Props {
|
|
249
|
+
readonly sidebar: BlogSidebar;
|
|
250
|
+
readonly metadata: Tag;
|
|
251
|
+
readonly listMetadata: Metadata;
|
|
252
|
+
readonly items: readonly {readonly content: Content}[];
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export default function BlogTagsPostsPage(props: Props): JSX.Element;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
declare module '@theme/BlogArchivePage' {
|
|
259
|
+
import type {Content} from '@theme/BlogPostPage';
|
|
260
|
+
|
|
261
|
+
export type ArchiveBlogPost = Content;
|
|
262
|
+
|
|
263
|
+
export interface Props {
|
|
264
|
+
readonly archive: {
|
|
265
|
+
readonly blogPosts: readonly ArchiveBlogPost[];
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export default function BlogArchivePage(props: Props): JSX.Element;
|
|
270
|
+
}
|
|
@@ -12,13 +12,15 @@ import {
|
|
|
12
12
|
AdmonitionsSchema,
|
|
13
13
|
URISchema,
|
|
14
14
|
} from '@docusaurus/utils-validation';
|
|
15
|
+
import {GlobExcludeDefault} from '@docusaurus/utils';
|
|
16
|
+
import type {PluginOptions} from '@docusaurus/plugin-content-blog';
|
|
15
17
|
|
|
16
|
-
export const DEFAULT_OPTIONS = {
|
|
17
|
-
feedOptions: {type: ['rss', 'atom']},
|
|
18
|
+
export const DEFAULT_OPTIONS: PluginOptions = {
|
|
19
|
+
feedOptions: {type: ['rss', 'atom'], copyright: ''},
|
|
18
20
|
beforeDefaultRehypePlugins: [],
|
|
19
21
|
beforeDefaultRemarkPlugins: [],
|
|
20
22
|
admonitions: {},
|
|
21
|
-
truncateMarker: /<!--\s*
|
|
23
|
+
truncateMarker: /<!--\s*truncate\s*-->/,
|
|
22
24
|
rehypePlugins: [],
|
|
23
25
|
remarkPlugins: [],
|
|
24
26
|
showReadingTime: true,
|
|
@@ -26,27 +28,38 @@ export const DEFAULT_OPTIONS = {
|
|
|
26
28
|
blogTagsListComponent: '@theme/BlogTagsListPage',
|
|
27
29
|
blogPostComponent: '@theme/BlogPostPage',
|
|
28
30
|
blogListComponent: '@theme/BlogListPage',
|
|
31
|
+
blogArchiveComponent: '@theme/BlogArchivePage',
|
|
29
32
|
blogDescription: 'Blog',
|
|
30
33
|
blogTitle: 'Blog',
|
|
31
34
|
blogSidebarCount: 5,
|
|
32
35
|
blogSidebarTitle: 'Recent posts',
|
|
33
36
|
postsPerPage: 10,
|
|
34
|
-
include: ['
|
|
37
|
+
include: ['**/*.{md,mdx}'],
|
|
38
|
+
exclude: GlobExcludeDefault,
|
|
35
39
|
routeBasePath: 'blog',
|
|
40
|
+
tagsBasePath: 'tags',
|
|
41
|
+
archiveBasePath: 'archive',
|
|
36
42
|
path: 'blog',
|
|
37
43
|
editLocalizedFiles: false,
|
|
44
|
+
authorsMapPath: 'authors.yml',
|
|
45
|
+
readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}),
|
|
46
|
+
sortPosts: 'descending',
|
|
38
47
|
};
|
|
39
48
|
|
|
40
|
-
export const PluginOptionSchema = Joi.object({
|
|
49
|
+
export const PluginOptionSchema = Joi.object<PluginOptions>({
|
|
41
50
|
path: Joi.string().default(DEFAULT_OPTIONS.path),
|
|
51
|
+
archiveBasePath: Joi.string()
|
|
52
|
+
.default(DEFAULT_OPTIONS.archiveBasePath)
|
|
53
|
+
.allow(null),
|
|
42
54
|
routeBasePath: Joi.string()
|
|
43
55
|
// '' not allowed, see https://github.com/facebook/docusaurus/issues/3374
|
|
44
56
|
// .allow('')
|
|
45
57
|
.default(DEFAULT_OPTIONS.routeBasePath),
|
|
58
|
+
tagsBasePath: Joi.string().default(DEFAULT_OPTIONS.tagsBasePath),
|
|
46
59
|
include: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.include),
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
.min(1)
|
|
60
|
+
exclude: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.exclude),
|
|
61
|
+
postsPerPage: Joi.alternatives()
|
|
62
|
+
.try(Joi.equal('ALL').required(), Joi.number().integer().min(1).required())
|
|
50
63
|
.default(DEFAULT_OPTIONS.postsPerPage),
|
|
51
64
|
blogListComponent: Joi.string().default(DEFAULT_OPTIONS.blogListComponent),
|
|
52
65
|
blogPostComponent: Joi.string().default(DEFAULT_OPTIONS.blogPostComponent),
|
|
@@ -56,12 +69,15 @@ export const PluginOptionSchema = Joi.object({
|
|
|
56
69
|
blogTagsPostsComponent: Joi.string().default(
|
|
57
70
|
DEFAULT_OPTIONS.blogTagsPostsComponent,
|
|
58
71
|
),
|
|
72
|
+
blogArchiveComponent: Joi.string().default(
|
|
73
|
+
DEFAULT_OPTIONS.blogArchiveComponent,
|
|
74
|
+
),
|
|
59
75
|
blogTitle: Joi.string().allow('').default(DEFAULT_OPTIONS.blogTitle),
|
|
60
76
|
blogDescription: Joi.string()
|
|
61
77
|
.allow('')
|
|
62
78
|
.default(DEFAULT_OPTIONS.blogDescription),
|
|
63
79
|
blogSidebarCount: Joi.alternatives()
|
|
64
|
-
.try(Joi.equal('ALL').required(), Joi.number().required())
|
|
80
|
+
.try(Joi.equal('ALL').required(), Joi.number().integer().min(0).required())
|
|
65
81
|
.default(DEFAULT_OPTIONS.blogSidebarCount),
|
|
66
82
|
blogSidebarTitle: Joi.string().default(DEFAULT_OPTIONS.blogSidebarTitle),
|
|
67
83
|
showReadingTime: Joi.bool().default(DEFAULT_OPTIONS.showReadingTime),
|
|
@@ -80,12 +96,12 @@ export const PluginOptionSchema = Joi.object({
|
|
|
80
96
|
feedOptions: Joi.object({
|
|
81
97
|
type: Joi.alternatives()
|
|
82
98
|
.try(
|
|
83
|
-
Joi.array().items(Joi.string()),
|
|
99
|
+
Joi.array().items(Joi.string().equal('rss', 'atom', 'json')),
|
|
84
100
|
Joi.alternatives().conditional(
|
|
85
|
-
Joi.string().equal('all', 'rss', 'atom'),
|
|
101
|
+
Joi.string().equal('all', 'rss', 'atom', 'json'),
|
|
86
102
|
{
|
|
87
103
|
then: Joi.custom((val) =>
|
|
88
|
-
val === 'all' ? ['rss', 'atom'] : [val],
|
|
104
|
+
val === 'all' ? ['rss', 'atom', 'json'] : [val],
|
|
89
105
|
),
|
|
90
106
|
},
|
|
91
107
|
),
|
|
@@ -94,7 +110,19 @@ export const PluginOptionSchema = Joi.object({
|
|
|
94
110
|
.default(DEFAULT_OPTIONS.feedOptions.type),
|
|
95
111
|
title: Joi.string().allow(''),
|
|
96
112
|
description: Joi.string().allow(''),
|
|
97
|
-
|
|
113
|
+
// only add default value when user actually wants a feed (type is not null)
|
|
114
|
+
copyright: Joi.when('type', {
|
|
115
|
+
is: Joi.any().valid(null),
|
|
116
|
+
then: Joi.string().optional(),
|
|
117
|
+
otherwise: Joi.string()
|
|
118
|
+
.allow('')
|
|
119
|
+
.default(DEFAULT_OPTIONS.feedOptions.copyright),
|
|
120
|
+
}),
|
|
98
121
|
language: Joi.string(),
|
|
99
122
|
}).default(DEFAULT_OPTIONS.feedOptions),
|
|
123
|
+
authorsMapPath: Joi.string().default(DEFAULT_OPTIONS.authorsMapPath),
|
|
124
|
+
readingTime: Joi.function().default(() => DEFAULT_OPTIONS.readingTime),
|
|
125
|
+
sortPosts: Joi.string()
|
|
126
|
+
.valid('descending', 'ascending')
|
|
127
|
+
.default(DEFAULT_OPTIONS.sortPosts),
|
|
100
128
|
});
|
|
@@ -0,0 +1,64 @@
|
|
|
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 type {BlogContent, BlogPaginated} from './types';
|
|
9
|
+
import type {TranslationFileContent, TranslationFiles} from '@docusaurus/types';
|
|
10
|
+
import type {PluginOptions} from '@docusaurus/plugin-content-blog';
|
|
11
|
+
|
|
12
|
+
function translateListPage(
|
|
13
|
+
blogListPaginated: BlogPaginated[],
|
|
14
|
+
translations: TranslationFileContent,
|
|
15
|
+
) {
|
|
16
|
+
return blogListPaginated.map((page) => {
|
|
17
|
+
const {items, metadata} = page;
|
|
18
|
+
return {
|
|
19
|
+
items,
|
|
20
|
+
metadata: {
|
|
21
|
+
...metadata,
|
|
22
|
+
blogTitle: translations.title.message,
|
|
23
|
+
blogDescription: translations.description.message,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function getTranslationFiles(options: PluginOptions): TranslationFiles {
|
|
30
|
+
return [
|
|
31
|
+
{
|
|
32
|
+
path: 'options',
|
|
33
|
+
content: {
|
|
34
|
+
title: {
|
|
35
|
+
message: options.blogTitle,
|
|
36
|
+
description: 'The title for the blog used in SEO',
|
|
37
|
+
},
|
|
38
|
+
description: {
|
|
39
|
+
message: options.blogDescription,
|
|
40
|
+
description: 'The description for the blog used in SEO',
|
|
41
|
+
},
|
|
42
|
+
'sidebar.title': {
|
|
43
|
+
message: options.blogSidebarTitle,
|
|
44
|
+
description: 'The label for the left sidebar',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function translateContent(
|
|
52
|
+
content: BlogContent,
|
|
53
|
+
translationFiles: TranslationFiles,
|
|
54
|
+
): BlogContent {
|
|
55
|
+
const [{content: optionsTranslations}] = translationFiles;
|
|
56
|
+
return {
|
|
57
|
+
...content,
|
|
58
|
+
blogSidebarTitle: optionsTranslations['sidebar.title'].message,
|
|
59
|
+
blogListPaginated: translateListPage(
|
|
60
|
+
content.blogListPaginated,
|
|
61
|
+
optionsTranslations,
|
|
62
|
+
),
|
|
63
|
+
};
|
|
64
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -5,76 +5,45 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type {
|
|
9
|
-
import {
|
|
8
|
+
import type {Tag} from '@docusaurus/utils';
|
|
9
|
+
import type {
|
|
10
10
|
BrokenMarkdownLink,
|
|
11
11
|
ContentPaths,
|
|
12
12
|
} from '@docusaurus/utils/lib/markdownLinks';
|
|
13
|
+
import type {
|
|
14
|
+
BlogPostFrontMatter,
|
|
15
|
+
Author,
|
|
16
|
+
} from '@docusaurus/plugin-content-blog';
|
|
13
17
|
|
|
14
18
|
export type BlogContentPaths = ContentPaths;
|
|
15
19
|
|
|
16
20
|
export interface BlogContent {
|
|
21
|
+
blogSidebarTitle: string;
|
|
17
22
|
blogPosts: BlogPost[];
|
|
18
23
|
blogListPaginated: BlogPaginated[];
|
|
19
24
|
blogTags: BlogTags;
|
|
20
25
|
blogTagsListPath: string | null;
|
|
21
26
|
}
|
|
22
27
|
|
|
23
|
-
export interface DateLink {
|
|
24
|
-
date: Date;
|
|
25
|
-
link: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export type FeedType = 'rss' | 'atom';
|
|
29
|
-
|
|
30
|
-
export type EditUrlFunction = (editUrlParams: {
|
|
31
|
-
blogDirPath: string;
|
|
32
|
-
blogPath: string;
|
|
33
|
-
permalink: string;
|
|
34
|
-
locale: string;
|
|
35
|
-
}) => string | undefined;
|
|
36
|
-
|
|
37
|
-
export interface PluginOptions extends RemarkAndRehypePluginOptions {
|
|
38
|
-
id?: string;
|
|
39
|
-
path: string;
|
|
40
|
-
routeBasePath: string;
|
|
41
|
-
include: string[];
|
|
42
|
-
postsPerPage: number;
|
|
43
|
-
blogListComponent: string;
|
|
44
|
-
blogPostComponent: string;
|
|
45
|
-
blogTagsListComponent: string;
|
|
46
|
-
blogTagsPostsComponent: string;
|
|
47
|
-
blogTitle: string;
|
|
48
|
-
blogDescription: string;
|
|
49
|
-
blogSidebarCount: number | 'ALL';
|
|
50
|
-
blogSidebarTitle: string;
|
|
51
|
-
truncateMarker: RegExp;
|
|
52
|
-
showReadingTime: boolean;
|
|
53
|
-
feedOptions: {
|
|
54
|
-
type?: [FeedType] | null;
|
|
55
|
-
title?: string;
|
|
56
|
-
description?: string;
|
|
57
|
-
copyright: string;
|
|
58
|
-
language?: string;
|
|
59
|
-
};
|
|
60
|
-
editUrl?: string | EditUrlFunction;
|
|
61
|
-
editLocalizedFiles?: boolean;
|
|
62
|
-
admonitions: Record<string, unknown>;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
28
|
export interface BlogTags {
|
|
66
|
-
|
|
29
|
+
// TODO, the key is the tag slug/permalink
|
|
30
|
+
// This is due to legacy frontmatter: tags:
|
|
31
|
+
// [{label: "xyz", permalink: "/1"}, {label: "xyz", permalink: "/2"}]
|
|
32
|
+
// Soon we should forbid declaring permalink through frontmatter
|
|
33
|
+
[tagKey: string]: BlogTag;
|
|
67
34
|
}
|
|
68
35
|
|
|
69
36
|
export interface BlogTag {
|
|
70
37
|
name: string;
|
|
71
|
-
items: string[];
|
|
38
|
+
items: string[]; // blog post permalinks
|
|
72
39
|
permalink: string;
|
|
40
|
+
pages: BlogPaginated[];
|
|
73
41
|
}
|
|
74
42
|
|
|
75
43
|
export interface BlogPost {
|
|
76
44
|
id: string;
|
|
77
45
|
metadata: MetaData;
|
|
46
|
+
content: string;
|
|
78
47
|
}
|
|
79
48
|
|
|
80
49
|
export interface BlogPaginatedMetadata {
|
|
@@ -91,7 +60,7 @@ export interface BlogPaginatedMetadata {
|
|
|
91
60
|
|
|
92
61
|
export interface BlogPaginated {
|
|
93
62
|
metadata: BlogPaginatedMetadata;
|
|
94
|
-
items: string[];
|
|
63
|
+
items: string[]; // blog post permalinks
|
|
95
64
|
}
|
|
96
65
|
|
|
97
66
|
export interface MetaData {
|
|
@@ -100,13 +69,15 @@ export interface MetaData {
|
|
|
100
69
|
description: string;
|
|
101
70
|
date: Date;
|
|
102
71
|
formattedDate: string;
|
|
103
|
-
tags:
|
|
72
|
+
tags: Tag[];
|
|
104
73
|
title: string;
|
|
105
74
|
readingTime?: number;
|
|
106
75
|
prevItem?: Paginator;
|
|
107
76
|
nextItem?: Paginator;
|
|
108
77
|
truncated: boolean;
|
|
109
78
|
editUrl?: string;
|
|
79
|
+
authors: Author[];
|
|
80
|
+
frontMatter: BlogPostFrontMatter & Record<string, unknown>;
|
|
110
81
|
}
|
|
111
82
|
|
|
112
83
|
export interface Paginator {
|
|
@@ -114,11 +85,6 @@ export interface Paginator {
|
|
|
114
85
|
permalink: string;
|
|
115
86
|
}
|
|
116
87
|
|
|
117
|
-
export interface Tag {
|
|
118
|
-
label: string;
|
|
119
|
-
permalink: string;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
88
|
export interface BlogItemsToMetadata {
|
|
123
89
|
[key: string]: MetaData;
|
|
124
90
|
}
|