@docusaurus/plugin-content-blog 3.5.0 → 3.5.2-canary-6121
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 +4 -0
- package/lib/authors.js +19 -2
- package/lib/authorsMap.d.ts +1 -0
- package/lib/authorsMap.js +5 -3
- package/lib/authorsSocials.js +4 -0
- package/lib/contentHelpers.d.ts +12 -0
- package/lib/contentHelpers.js +30 -0
- package/lib/index.js +75 -92
- package/lib/options.js +1 -1
- package/package.json +11 -11
- package/src/authors.ts +33 -5
- package/src/authorsMap.ts +10 -3
- package/src/authorsSocials.ts +6 -0
- package/src/contentHelpers.ts +35 -0
- package/src/index.ts +99 -128
- package/src/options.ts +1 -1
package/lib/authors.d.ts
CHANGED
|
@@ -10,6 +10,10 @@ type AuthorsParam = {
|
|
|
10
10
|
authorsMap: AuthorsMap | undefined;
|
|
11
11
|
baseUrl: string;
|
|
12
12
|
};
|
|
13
|
+
export declare function normalizeImageUrl({ imageURL, baseUrl, }: {
|
|
14
|
+
imageURL: string | undefined;
|
|
15
|
+
baseUrl: string;
|
|
16
|
+
}): string | undefined;
|
|
13
17
|
export declare function getBlogPostAuthors(params: AuthorsParam): Author[];
|
|
14
18
|
/**
|
|
15
19
|
* Group blog posts by author key
|
package/lib/authors.js
CHANGED
|
@@ -6,16 +6,29 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.normalizeImageUrl = normalizeImageUrl;
|
|
9
10
|
exports.getBlogPostAuthors = getBlogPostAuthors;
|
|
10
11
|
exports.groupBlogPostsByAuthorKey = groupBlogPostsByAuthorKey;
|
|
11
12
|
const tslib_1 = require("tslib");
|
|
12
13
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
13
14
|
const utils_1 = require("@docusaurus/utils");
|
|
15
|
+
const authorsSocials_1 = require("./authorsSocials");
|
|
14
16
|
function normalizeImageUrl({ imageURL, baseUrl, }) {
|
|
15
17
|
return imageURL?.startsWith('/')
|
|
16
18
|
? (0, utils_1.normalizeUrl)([baseUrl, imageURL])
|
|
17
19
|
: imageURL;
|
|
18
20
|
}
|
|
21
|
+
function normalizeAuthorUrl({ author, baseUrl, }) {
|
|
22
|
+
if (author.key) {
|
|
23
|
+
// Ensures invariant: global authors should have already been normalized
|
|
24
|
+
if (author.imageURL?.startsWith('/') &&
|
|
25
|
+
!author.imageURL.startsWith(baseUrl)) {
|
|
26
|
+
throw new Error(`Docusaurus internal bug: global authors image ${author.imageURL} should start with the expected baseUrl=${baseUrl}`);
|
|
27
|
+
}
|
|
28
|
+
return author.imageURL;
|
|
29
|
+
}
|
|
30
|
+
return normalizeImageUrl({ imageURL: author.imageURL, baseUrl });
|
|
31
|
+
}
|
|
19
32
|
// Legacy v1/early-v2 front matter fields
|
|
20
33
|
// We may want to deprecate those in favor of using only frontMatter.authors
|
|
21
34
|
// TODO Docusaurus v4: remove this legacy front matter
|
|
@@ -54,7 +67,10 @@ function getFrontMatterAuthors(params) {
|
|
|
54
67
|
// becoming a name and may end up unnoticed
|
|
55
68
|
return { key: authorInput };
|
|
56
69
|
}
|
|
57
|
-
return
|
|
70
|
+
return {
|
|
71
|
+
...authorInput,
|
|
72
|
+
socials: (0, authorsSocials_1.normalizeSocials)(authorInput.socials ?? {}),
|
|
73
|
+
};
|
|
58
74
|
}
|
|
59
75
|
return Array.isArray(frontMatter.authors)
|
|
60
76
|
? frontMatter.authors.map(normalizeAuthor)
|
|
@@ -88,7 +104,8 @@ ${Object.keys(authorsMap)
|
|
|
88
104
|
...author,
|
|
89
105
|
key: author.key ?? null,
|
|
90
106
|
page: author.page ?? null,
|
|
91
|
-
|
|
107
|
+
// global author images have already been normalized
|
|
108
|
+
imageURL: normalizeAuthorUrl({ author, baseUrl }),
|
|
92
109
|
};
|
|
93
110
|
}
|
|
94
111
|
}
|
package/lib/authorsMap.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export declare function getAuthorsMap(params: {
|
|
|
18
18
|
authorsMapPath: string;
|
|
19
19
|
authorsBaseRoutePath: string;
|
|
20
20
|
contentPaths: BlogContentPaths;
|
|
21
|
+
baseUrl: string;
|
|
21
22
|
}): Promise<AuthorsMap | undefined>;
|
|
22
23
|
export declare function validateAuthorsMap(content: unknown): AuthorsMapInput;
|
|
23
24
|
export {};
|
package/lib/authorsMap.js
CHANGED
|
@@ -15,6 +15,7 @@ const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
|
15
15
|
const utils_1 = require("@docusaurus/utils");
|
|
16
16
|
const utils_validation_1 = require("@docusaurus/utils-validation");
|
|
17
17
|
const authorsSocials_1 = require("./authorsSocials");
|
|
18
|
+
const authors_1 = require("./authors");
|
|
18
19
|
const AuthorPageSchema = utils_validation_1.Joi.object({
|
|
19
20
|
permalink: utils_validation_1.Joi.string().required(),
|
|
20
21
|
});
|
|
@@ -63,7 +64,7 @@ function checkAuthorsMapPermalinkCollisions(authorsMap) {
|
|
|
63
64
|
throw new Error(`The following permalinks are duplicated:\n${errorMessage}`);
|
|
64
65
|
}
|
|
65
66
|
}
|
|
66
|
-
function normalizeAuthor({ authorsBaseRoutePath, authorKey, author, }) {
|
|
67
|
+
function normalizeAuthor({ authorsBaseRoutePath, authorKey, baseUrl, author, }) {
|
|
67
68
|
function getAuthorPage() {
|
|
68
69
|
if (!author.page) {
|
|
69
70
|
return null;
|
|
@@ -77,12 +78,13 @@ function normalizeAuthor({ authorsBaseRoutePath, authorKey, author, }) {
|
|
|
77
78
|
...author,
|
|
78
79
|
key: authorKey,
|
|
79
80
|
page: getAuthorPage(),
|
|
81
|
+
imageURL: (0, authors_1.normalizeImageUrl)({ imageURL: author.imageURL, baseUrl }),
|
|
80
82
|
socials: author.socials ? (0, authorsSocials_1.normalizeSocials)(author.socials) : undefined,
|
|
81
83
|
};
|
|
82
84
|
}
|
|
83
|
-
function normalizeAuthorsMap({ authorsBaseRoutePath, authorsMapInput, }) {
|
|
85
|
+
function normalizeAuthorsMap({ authorsBaseRoutePath, authorsMapInput, baseUrl, }) {
|
|
84
86
|
return lodash_1.default.mapValues(authorsMapInput, (author, authorKey) => {
|
|
85
|
-
return normalizeAuthor({ authorsBaseRoutePath, authorKey, author });
|
|
87
|
+
return normalizeAuthor({ authorsBaseRoutePath, authorKey, author, baseUrl });
|
|
86
88
|
});
|
|
87
89
|
}
|
|
88
90
|
function validateAuthorsMapInput(content) {
|
package/lib/authorsSocials.js
CHANGED
|
@@ -27,6 +27,10 @@ const PredefinedPlatformNormalizers = {
|
|
|
27
27
|
};
|
|
28
28
|
function normalizeSocialEntry([platform, value]) {
|
|
29
29
|
const normalizer = PredefinedPlatformNormalizers[platform.toLowerCase()];
|
|
30
|
+
if (typeof value !== 'string') {
|
|
31
|
+
throw new Error(`Author socials should be usernames/userIds/handles, or fully qualified HTTP(s) absolute URLs.
|
|
32
|
+
Social platform '${platform}' has illegal value '${value}'`);
|
|
33
|
+
}
|
|
30
34
|
const isAbsoluteUrl = value.startsWith('http://') || value.startsWith('https://');
|
|
31
35
|
if (isAbsoluteUrl) {
|
|
32
36
|
return [platform, value];
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
import type { BlogContent, BlogPost } from '@docusaurus/plugin-content-blog';
|
|
8
|
+
export declare function createContentHelpers(): {
|
|
9
|
+
updateContent: (content: BlogContent) => void;
|
|
10
|
+
sourceToBlogPost: Map<string, BlogPost>;
|
|
11
|
+
sourceToPermalink: Map<string, string>;
|
|
12
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.createContentHelpers = createContentHelpers;
|
|
10
|
+
function indexBlogPostsBySource(content) {
|
|
11
|
+
return new Map(content.blogPosts.map((blogPost) => [blogPost.metadata.source, blogPost]));
|
|
12
|
+
}
|
|
13
|
+
// TODO this is bad, we should have a better way to do this (new lifecycle?)
|
|
14
|
+
// The source to blog/permalink is a mutable map passed to the mdx loader
|
|
15
|
+
// See https://github.com/facebook/docusaurus/pull/10457
|
|
16
|
+
// See https://github.com/facebook/docusaurus/pull/10185
|
|
17
|
+
function createContentHelpers() {
|
|
18
|
+
const sourceToBlogPost = new Map();
|
|
19
|
+
const sourceToPermalink = new Map();
|
|
20
|
+
// Mutable map update :/
|
|
21
|
+
function updateContent(content) {
|
|
22
|
+
sourceToBlogPost.clear();
|
|
23
|
+
sourceToPermalink.clear();
|
|
24
|
+
indexBlogPostsBySource(content).forEach((value, key) => {
|
|
25
|
+
sourceToBlogPost.set(key, value);
|
|
26
|
+
sourceToPermalink.set(key, value.metadata.permalink);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
return { updateContent, sourceToBlogPost, sourceToPermalink };
|
|
30
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -13,34 +13,15 @@ const path_1 = tslib_1.__importDefault(require("path"));
|
|
|
13
13
|
const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
|
|
14
14
|
const utils_1 = require("@docusaurus/utils");
|
|
15
15
|
const utils_validation_1 = require("@docusaurus/utils-validation");
|
|
16
|
+
const mdx_loader_1 = require("@docusaurus/mdx-loader");
|
|
16
17
|
const blogUtils_1 = require("./blogUtils");
|
|
17
18
|
const footnoteIDFixer_1 = tslib_1.__importDefault(require("./remark/footnoteIDFixer"));
|
|
18
19
|
const translations_1 = require("./translations");
|
|
19
20
|
const feed_1 = require("./feed");
|
|
20
21
|
const routes_1 = require("./routes");
|
|
21
22
|
const authorsMap_1 = require("./authorsMap");
|
|
23
|
+
const contentHelpers_1 = require("./contentHelpers");
|
|
22
24
|
const PluginName = 'docusaurus-plugin-content-blog';
|
|
23
|
-
// TODO this is bad, we should have a better way to do this (new lifecycle?)
|
|
24
|
-
// The source to permalink is currently a mutable map passed to the mdx loader
|
|
25
|
-
// for link resolution
|
|
26
|
-
// see https://github.com/facebook/docusaurus/pull/10185
|
|
27
|
-
function createSourceToPermalinkHelper() {
|
|
28
|
-
const sourceToPermalink = new Map();
|
|
29
|
-
function computeSourceToPermalink(content) {
|
|
30
|
-
return new Map(content.blogPosts.map(({ metadata: { source, permalink } }) => [
|
|
31
|
-
source,
|
|
32
|
-
permalink,
|
|
33
|
-
]));
|
|
34
|
-
}
|
|
35
|
-
// Mutable map update :/
|
|
36
|
-
function update(content) {
|
|
37
|
-
sourceToPermalink.clear();
|
|
38
|
-
computeSourceToPermalink(content).forEach((value, key) => {
|
|
39
|
-
sourceToPermalink.set(key, value);
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
return { get: () => sourceToPermalink, update };
|
|
43
|
-
}
|
|
44
25
|
async function pluginContentBlog(context, options) {
|
|
45
26
|
const { siteDir, siteConfig, generatedFilesDir, localizationDir, i18n: { currentLocale }, } = context;
|
|
46
27
|
const router = siteConfig.future.experimental_router;
|
|
@@ -68,7 +49,76 @@ async function pluginContentBlog(context, options) {
|
|
|
68
49
|
filePath: options.authorsMapPath,
|
|
69
50
|
contentPaths,
|
|
70
51
|
});
|
|
71
|
-
const
|
|
52
|
+
const contentHelpers = (0, contentHelpers_1.createContentHelpers)();
|
|
53
|
+
async function createBlogMDXLoaderRule() {
|
|
54
|
+
const { admonitions, rehypePlugins, remarkPlugins, recmaPlugins, truncateMarker, beforeDefaultRemarkPlugins, beforeDefaultRehypePlugins, } = options;
|
|
55
|
+
const contentDirs = (0, utils_1.getContentPathList)(contentPaths);
|
|
56
|
+
const mdxLoaderItem = await (0, mdx_loader_1.createMDXLoaderItem)({
|
|
57
|
+
useCrossCompilerCache: siteConfig.future.experimental_faster.mdxCrossCompilerCache,
|
|
58
|
+
admonitions,
|
|
59
|
+
remarkPlugins,
|
|
60
|
+
rehypePlugins,
|
|
61
|
+
recmaPlugins,
|
|
62
|
+
beforeDefaultRemarkPlugins: [
|
|
63
|
+
footnoteIDFixer_1.default,
|
|
64
|
+
...beforeDefaultRemarkPlugins,
|
|
65
|
+
],
|
|
66
|
+
beforeDefaultRehypePlugins,
|
|
67
|
+
staticDirs: siteConfig.staticDirectories.map((dir) => path_1.default.resolve(siteDir, dir)),
|
|
68
|
+
siteDir,
|
|
69
|
+
isMDXPartial: (0, utils_1.createAbsoluteFilePathMatcher)(options.exclude, contentDirs),
|
|
70
|
+
metadataPath: (mdxPath) => {
|
|
71
|
+
// Note that metadataPath must be the same/in-sync as
|
|
72
|
+
// the path from createData for each MDX.
|
|
73
|
+
const aliasedPath = (0, utils_1.aliasedSitePath)(mdxPath, siteDir);
|
|
74
|
+
return path_1.default.join(dataDir, `${(0, utils_1.docuHash)(aliasedPath)}.json`);
|
|
75
|
+
},
|
|
76
|
+
// For blog posts a title in markdown is always removed
|
|
77
|
+
// Blog posts title are rendered separately
|
|
78
|
+
removeContentTitle: true,
|
|
79
|
+
// createAssets converts relative paths to require() calls
|
|
80
|
+
createAssets: ({ filePath }) => {
|
|
81
|
+
const blogPost = contentHelpers.sourceToBlogPost.get((0, utils_1.aliasedSitePath)(filePath, siteDir));
|
|
82
|
+
if (!blogPost) {
|
|
83
|
+
throw new Error(`Blog post not found for filePath=${filePath}`);
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
image: blogPost.metadata.frontMatter.image,
|
|
87
|
+
authorsImageUrls: blogPost.metadata.authors.map((author) => author.imageURL),
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
markdownConfig: siteConfig.markdown,
|
|
91
|
+
resolveMarkdownLink: ({ linkPathname, sourceFilePath }) => {
|
|
92
|
+
const permalink = (0, utils_1.resolveMarkdownLinkPathname)(linkPathname, {
|
|
93
|
+
sourceFilePath,
|
|
94
|
+
sourceToPermalink: contentHelpers.sourceToPermalink,
|
|
95
|
+
siteDir,
|
|
96
|
+
contentPaths,
|
|
97
|
+
});
|
|
98
|
+
if (permalink === null) {
|
|
99
|
+
logger_1.default.report(onBrokenMarkdownLinks) `Blog markdown link couldn't be resolved: (url=${linkPathname}) in source file path=${sourceFilePath}`;
|
|
100
|
+
}
|
|
101
|
+
return permalink;
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
function createBlogMarkdownLoader() {
|
|
105
|
+
const markdownLoaderOptions = {
|
|
106
|
+
truncateMarker,
|
|
107
|
+
};
|
|
108
|
+
return {
|
|
109
|
+
loader: path_1.default.resolve(__dirname, './markdownLoader.js'),
|
|
110
|
+
options: markdownLoaderOptions,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
test: /\.mdx?$/i,
|
|
115
|
+
include: contentDirs
|
|
116
|
+
// Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
|
|
117
|
+
.map(utils_1.addTrailingPathSeparator),
|
|
118
|
+
use: [mdxLoaderItem, createBlogMarkdownLoader()],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
const blogMDXLoaderRule = await createBlogMDXLoaderRule();
|
|
72
122
|
return {
|
|
73
123
|
name: PluginName,
|
|
74
124
|
getPathsToWatch() {
|
|
@@ -100,6 +150,7 @@ async function pluginContentBlog(context, options) {
|
|
|
100
150
|
routeBasePath,
|
|
101
151
|
authorsBasePath,
|
|
102
152
|
]),
|
|
153
|
+
baseUrl,
|
|
103
154
|
});
|
|
104
155
|
(0, authorsMap_1.checkAuthorsMapPermalinkCollisions)(authorsMap);
|
|
105
156
|
let blogPosts = await (0, blogUtils_1.generateBlogPosts)(contentPaths, context, options, authorsMap);
|
|
@@ -166,7 +217,7 @@ async function pluginContentBlog(context, options) {
|
|
|
166
217
|
};
|
|
167
218
|
},
|
|
168
219
|
async contentLoaded({ content, actions }) {
|
|
169
|
-
|
|
220
|
+
contentHelpers.updateContent(content);
|
|
170
221
|
await (0, routes_1.createAllRoutes)({
|
|
171
222
|
baseUrl,
|
|
172
223
|
content,
|
|
@@ -179,66 +230,6 @@ async function pluginContentBlog(context, options) {
|
|
|
179
230
|
return (0, translations_1.translateContent)(content, translationFiles);
|
|
180
231
|
},
|
|
181
232
|
configureWebpack() {
|
|
182
|
-
const { admonitions, rehypePlugins, remarkPlugins, recmaPlugins, truncateMarker, beforeDefaultRemarkPlugins, beforeDefaultRehypePlugins, } = options;
|
|
183
|
-
const contentDirs = (0, utils_1.getContentPathList)(contentPaths);
|
|
184
|
-
function createMDXLoader() {
|
|
185
|
-
const loaderOptions = {
|
|
186
|
-
admonitions,
|
|
187
|
-
remarkPlugins,
|
|
188
|
-
rehypePlugins,
|
|
189
|
-
recmaPlugins,
|
|
190
|
-
beforeDefaultRemarkPlugins: [
|
|
191
|
-
footnoteIDFixer_1.default,
|
|
192
|
-
...beforeDefaultRemarkPlugins,
|
|
193
|
-
],
|
|
194
|
-
beforeDefaultRehypePlugins,
|
|
195
|
-
staticDirs: siteConfig.staticDirectories.map((dir) => path_1.default.resolve(siteDir, dir)),
|
|
196
|
-
siteDir,
|
|
197
|
-
isMDXPartial: (0, utils_1.createAbsoluteFilePathMatcher)(options.exclude, contentDirs),
|
|
198
|
-
metadataPath: (mdxPath) => {
|
|
199
|
-
// Note that metadataPath must be the same/in-sync as
|
|
200
|
-
// the path from createData for each MDX.
|
|
201
|
-
const aliasedPath = (0, utils_1.aliasedSitePath)(mdxPath, siteDir);
|
|
202
|
-
return path_1.default.join(dataDir, `${(0, utils_1.docuHash)(aliasedPath)}.json`);
|
|
203
|
-
},
|
|
204
|
-
// For blog posts a title in markdown is always removed
|
|
205
|
-
// Blog posts title are rendered separately
|
|
206
|
-
removeContentTitle: true,
|
|
207
|
-
// Assets allow to convert some relative images paths to
|
|
208
|
-
// require() calls
|
|
209
|
-
// @ts-expect-error: TODO fix typing issue
|
|
210
|
-
createAssets: ({ frontMatter, metadata, }) => ({
|
|
211
|
-
image: frontMatter.image,
|
|
212
|
-
authorsImageUrls: metadata.authors.map((author) => author.imageURL),
|
|
213
|
-
}),
|
|
214
|
-
markdownConfig: siteConfig.markdown,
|
|
215
|
-
resolveMarkdownLink: ({ linkPathname, sourceFilePath }) => {
|
|
216
|
-
const permalink = (0, utils_1.resolveMarkdownLinkPathname)(linkPathname, {
|
|
217
|
-
sourceFilePath,
|
|
218
|
-
sourceToPermalink: sourceToPermalinkHelper.get(),
|
|
219
|
-
siteDir,
|
|
220
|
-
contentPaths,
|
|
221
|
-
});
|
|
222
|
-
if (permalink === null) {
|
|
223
|
-
logger_1.default.report(onBrokenMarkdownLinks) `Blog markdown link couldn't be resolved: (url=${linkPathname}) in source file path=${sourceFilePath}`;
|
|
224
|
-
}
|
|
225
|
-
return permalink;
|
|
226
|
-
},
|
|
227
|
-
};
|
|
228
|
-
return {
|
|
229
|
-
loader: require.resolve('@docusaurus/mdx-loader'),
|
|
230
|
-
options: loaderOptions,
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
function createBlogMarkdownLoader() {
|
|
234
|
-
const loaderOptions = {
|
|
235
|
-
truncateMarker,
|
|
236
|
-
};
|
|
237
|
-
return {
|
|
238
|
-
loader: path_1.default.resolve(__dirname, './markdownLoader.js'),
|
|
239
|
-
options: loaderOptions,
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
233
|
return {
|
|
243
234
|
resolve: {
|
|
244
235
|
alias: {
|
|
@@ -246,15 +237,7 @@ async function pluginContentBlog(context, options) {
|
|
|
246
237
|
},
|
|
247
238
|
},
|
|
248
239
|
module: {
|
|
249
|
-
rules: [
|
|
250
|
-
{
|
|
251
|
-
test: /\.mdx?$/i,
|
|
252
|
-
include: contentDirs
|
|
253
|
-
// Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
|
|
254
|
-
.map(utils_1.addTrailingPathSeparator),
|
|
255
|
-
use: [createMDXLoader(), createBlogMarkdownLoader()],
|
|
256
|
-
},
|
|
257
|
-
],
|
|
240
|
+
rules: [blogMDXLoaderRule],
|
|
258
241
|
},
|
|
259
242
|
};
|
|
260
243
|
},
|
package/lib/options.js
CHANGED
|
@@ -56,9 +56,9 @@ exports.DEFAULT_OPTIONS = {
|
|
|
56
56
|
showLastUpdateTime: false,
|
|
57
57
|
showLastUpdateAuthor: false,
|
|
58
58
|
processBlogPosts: async () => undefined,
|
|
59
|
-
onInlineTags: 'warn',
|
|
60
59
|
tags: undefined,
|
|
61
60
|
authorsBasePath: 'authors',
|
|
61
|
+
onInlineTags: 'warn',
|
|
62
62
|
onInlineAuthors: 'warn',
|
|
63
63
|
onUntruncatedBlogPosts: 'warn',
|
|
64
64
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docusaurus/plugin-content-blog",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.2-canary-6121",
|
|
4
4
|
"description": "Blog plugin for Docusaurus.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "src/plugin-content-blog.d.ts",
|
|
@@ -31,15 +31,15 @@
|
|
|
31
31
|
},
|
|
32
32
|
"license": "MIT",
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@docusaurus/core": "3.5.
|
|
35
|
-
"@docusaurus/logger": "3.5.
|
|
36
|
-
"@docusaurus/mdx-loader": "3.5.
|
|
37
|
-
"@docusaurus/theme-common": "3.5.
|
|
38
|
-
"@docusaurus/types": "3.5.
|
|
39
|
-
"@docusaurus/utils": "3.5.
|
|
40
|
-
"@docusaurus/utils-common": "3.5.
|
|
41
|
-
"@docusaurus/utils-validation": "3.5.
|
|
42
|
-
"cheerio": "
|
|
34
|
+
"@docusaurus/core": "3.5.2-canary-6121",
|
|
35
|
+
"@docusaurus/logger": "3.5.2-canary-6121",
|
|
36
|
+
"@docusaurus/mdx-loader": "3.5.2-canary-6121",
|
|
37
|
+
"@docusaurus/theme-common": "3.5.2-canary-6121",
|
|
38
|
+
"@docusaurus/types": "3.5.2-canary-6121",
|
|
39
|
+
"@docusaurus/utils": "3.5.2-canary-6121",
|
|
40
|
+
"@docusaurus/utils-common": "3.5.2-canary-6121",
|
|
41
|
+
"@docusaurus/utils-validation": "3.5.2-canary-6121",
|
|
42
|
+
"cheerio": "1.0.0-rc.12",
|
|
43
43
|
"feed": "^4.2.2",
|
|
44
44
|
"fs-extra": "^11.1.1",
|
|
45
45
|
"lodash": "^4.17.21",
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
"@total-typescript/shoehorn": "^0.1.2",
|
|
63
63
|
"tree-node-cli": "^1.6.0"
|
|
64
64
|
},
|
|
65
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "896e16cdd4bdd1811d287dc60ff932ca00be57e4"
|
|
66
66
|
}
|
package/src/authors.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import _ from 'lodash';
|
|
9
9
|
import {normalizeUrl} from '@docusaurus/utils';
|
|
10
|
+
import {normalizeSocials} from './authorsSocials';
|
|
10
11
|
import type {
|
|
11
12
|
Author,
|
|
12
13
|
AuthorsMap,
|
|
@@ -21,18 +22,41 @@ type AuthorsParam = {
|
|
|
21
22
|
baseUrl: string;
|
|
22
23
|
};
|
|
23
24
|
|
|
24
|
-
function normalizeImageUrl({
|
|
25
|
+
export function normalizeImageUrl({
|
|
25
26
|
imageURL,
|
|
26
27
|
baseUrl,
|
|
27
28
|
}: {
|
|
28
29
|
imageURL: string | undefined;
|
|
29
30
|
baseUrl: string;
|
|
30
|
-
}) {
|
|
31
|
+
}): string | undefined {
|
|
31
32
|
return imageURL?.startsWith('/')
|
|
32
33
|
? normalizeUrl([baseUrl, imageURL])
|
|
33
34
|
: imageURL;
|
|
34
35
|
}
|
|
35
36
|
|
|
37
|
+
function normalizeAuthorUrl({
|
|
38
|
+
author,
|
|
39
|
+
baseUrl,
|
|
40
|
+
}: {
|
|
41
|
+
author: Author;
|
|
42
|
+
baseUrl: string;
|
|
43
|
+
}): string | undefined {
|
|
44
|
+
if (author.key) {
|
|
45
|
+
// Ensures invariant: global authors should have already been normalized
|
|
46
|
+
if (
|
|
47
|
+
author.imageURL?.startsWith('/') &&
|
|
48
|
+
!author.imageURL.startsWith(baseUrl)
|
|
49
|
+
) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`Docusaurus internal bug: global authors image ${author.imageURL} should start with the expected baseUrl=${baseUrl}`,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return author.imageURL;
|
|
56
|
+
}
|
|
57
|
+
return normalizeImageUrl({imageURL: author.imageURL, baseUrl});
|
|
58
|
+
}
|
|
59
|
+
|
|
36
60
|
// Legacy v1/early-v2 front matter fields
|
|
37
61
|
// We may want to deprecate those in favor of using only frontMatter.authors
|
|
38
62
|
// TODO Docusaurus v4: remove this legacy front matter
|
|
@@ -84,7 +108,10 @@ function getFrontMatterAuthors(params: AuthorsParam): Author[] {
|
|
|
84
108
|
// becoming a name and may end up unnoticed
|
|
85
109
|
return {key: authorInput};
|
|
86
110
|
}
|
|
87
|
-
return
|
|
111
|
+
return {
|
|
112
|
+
...authorInput,
|
|
113
|
+
socials: normalizeSocials(authorInput.socials ?? {}),
|
|
114
|
+
};
|
|
88
115
|
}
|
|
89
116
|
|
|
90
117
|
return Array.isArray(frontMatter.authors)
|
|
@@ -116,13 +143,14 @@ ${Object.keys(authorsMap)
|
|
|
116
143
|
// Author def from authorsMap can be locally overridden by front matter
|
|
117
144
|
...getAuthorsMapAuthor(frontMatterAuthor.key),
|
|
118
145
|
...frontMatterAuthor,
|
|
119
|
-
};
|
|
146
|
+
} as Author;
|
|
120
147
|
|
|
121
148
|
return {
|
|
122
149
|
...author,
|
|
123
150
|
key: author.key ?? null,
|
|
124
151
|
page: author.page ?? null,
|
|
125
|
-
|
|
152
|
+
// global author images have already been normalized
|
|
153
|
+
imageURL: normalizeAuthorUrl({author, baseUrl}),
|
|
126
154
|
};
|
|
127
155
|
}
|
|
128
156
|
}
|
package/src/authorsMap.ts
CHANGED
|
@@ -9,12 +9,13 @@ import _ from 'lodash';
|
|
|
9
9
|
import {readDataFile, normalizeUrl} from '@docusaurus/utils';
|
|
10
10
|
import {Joi, URISchema} from '@docusaurus/utils-validation';
|
|
11
11
|
import {AuthorSocialsSchema, normalizeSocials} from './authorsSocials';
|
|
12
|
+
import {normalizeImageUrl} from './authors';
|
|
12
13
|
import type {BlogContentPaths} from './types';
|
|
13
14
|
import type {
|
|
14
|
-
Author,
|
|
15
15
|
AuthorAttributes,
|
|
16
16
|
AuthorPage,
|
|
17
17
|
AuthorsMap,
|
|
18
|
+
AuthorWithKey,
|
|
18
19
|
} from '@docusaurus/plugin-content-blog';
|
|
19
20
|
|
|
20
21
|
type AuthorInput = AuthorAttributes & {
|
|
@@ -93,12 +94,14 @@ export function checkAuthorsMapPermalinkCollisions(
|
|
|
93
94
|
function normalizeAuthor({
|
|
94
95
|
authorsBaseRoutePath,
|
|
95
96
|
authorKey,
|
|
97
|
+
baseUrl,
|
|
96
98
|
author,
|
|
97
99
|
}: {
|
|
98
100
|
authorsBaseRoutePath: string;
|
|
99
101
|
authorKey: string;
|
|
102
|
+
baseUrl: string;
|
|
100
103
|
author: AuthorInput;
|
|
101
|
-
}):
|
|
104
|
+
}): AuthorWithKey {
|
|
102
105
|
function getAuthorPage(): AuthorPage | null {
|
|
103
106
|
if (!author.page) {
|
|
104
107
|
return null;
|
|
@@ -114,6 +117,7 @@ function normalizeAuthor({
|
|
|
114
117
|
...author,
|
|
115
118
|
key: authorKey,
|
|
116
119
|
page: getAuthorPage(),
|
|
120
|
+
imageURL: normalizeImageUrl({imageURL: author.imageURL, baseUrl}),
|
|
117
121
|
socials: author.socials ? normalizeSocials(author.socials) : undefined,
|
|
118
122
|
};
|
|
119
123
|
}
|
|
@@ -121,12 +125,14 @@ function normalizeAuthor({
|
|
|
121
125
|
function normalizeAuthorsMap({
|
|
122
126
|
authorsBaseRoutePath,
|
|
123
127
|
authorsMapInput,
|
|
128
|
+
baseUrl,
|
|
124
129
|
}: {
|
|
125
130
|
authorsBaseRoutePath: string;
|
|
126
131
|
authorsMapInput: AuthorsMapInput;
|
|
132
|
+
baseUrl: string;
|
|
127
133
|
}): AuthorsMap {
|
|
128
134
|
return _.mapValues(authorsMapInput, (author, authorKey) => {
|
|
129
|
-
return normalizeAuthor({authorsBaseRoutePath, authorKey, author});
|
|
135
|
+
return normalizeAuthor({authorsBaseRoutePath, authorKey, author, baseUrl});
|
|
130
136
|
});
|
|
131
137
|
}
|
|
132
138
|
|
|
@@ -153,6 +159,7 @@ export async function getAuthorsMap(params: {
|
|
|
153
159
|
authorsMapPath: string;
|
|
154
160
|
authorsBaseRoutePath: string;
|
|
155
161
|
contentPaths: BlogContentPaths;
|
|
162
|
+
baseUrl: string;
|
|
156
163
|
}): Promise<AuthorsMap | undefined> {
|
|
157
164
|
const authorsMapInput = await getAuthorsMapInput(params);
|
|
158
165
|
if (!authorsMapInput) {
|
package/src/authorsSocials.ts
CHANGED
|
@@ -41,6 +41,12 @@ type SocialEntry = [string, string];
|
|
|
41
41
|
|
|
42
42
|
function normalizeSocialEntry([platform, value]: SocialEntry): SocialEntry {
|
|
43
43
|
const normalizer = PredefinedPlatformNormalizers[platform.toLowerCase()];
|
|
44
|
+
if (typeof value !== 'string') {
|
|
45
|
+
throw new Error(
|
|
46
|
+
`Author socials should be usernames/userIds/handles, or fully qualified HTTP(s) absolute URLs.
|
|
47
|
+
Social platform '${platform}' has illegal value '${value}'`,
|
|
48
|
+
);
|
|
49
|
+
}
|
|
44
50
|
const isAbsoluteUrl =
|
|
45
51
|
value.startsWith('http://') || value.startsWith('https://');
|
|
46
52
|
if (isAbsoluteUrl) {
|
|
@@ -0,0 +1,35 @@
|
|
|
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, BlogPost} from '@docusaurus/plugin-content-blog';
|
|
9
|
+
|
|
10
|
+
function indexBlogPostsBySource(content: BlogContent): Map<string, BlogPost> {
|
|
11
|
+
return new Map(
|
|
12
|
+
content.blogPosts.map((blogPost) => [blogPost.metadata.source, blogPost]),
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// TODO this is bad, we should have a better way to do this (new lifecycle?)
|
|
17
|
+
// The source to blog/permalink is a mutable map passed to the mdx loader
|
|
18
|
+
// See https://github.com/facebook/docusaurus/pull/10457
|
|
19
|
+
// See https://github.com/facebook/docusaurus/pull/10185
|
|
20
|
+
export function createContentHelpers() {
|
|
21
|
+
const sourceToBlogPost = new Map<string, BlogPost>();
|
|
22
|
+
const sourceToPermalink = new Map<string, string>();
|
|
23
|
+
|
|
24
|
+
// Mutable map update :/
|
|
25
|
+
function updateContent(content: BlogContent): void {
|
|
26
|
+
sourceToBlogPost.clear();
|
|
27
|
+
sourceToPermalink.clear();
|
|
28
|
+
indexBlogPostsBySource(content).forEach((value, key) => {
|
|
29
|
+
sourceToBlogPost.set(key, value);
|
|
30
|
+
sourceToPermalink.set(key, value.metadata.permalink);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return {updateContent, sourceToBlogPost, sourceToPermalink};
|
|
35
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -19,9 +19,9 @@ import {
|
|
|
19
19
|
getDataFilePath,
|
|
20
20
|
DEFAULT_PLUGIN_ID,
|
|
21
21
|
resolveMarkdownLinkPathname,
|
|
22
|
-
type SourceToPermalink,
|
|
23
22
|
} from '@docusaurus/utils';
|
|
24
23
|
import {getTagsFilePathsToWatch} from '@docusaurus/utils-validation';
|
|
24
|
+
import {createMDXLoaderItem} from '@docusaurus/mdx-loader';
|
|
25
25
|
import {
|
|
26
26
|
getBlogTags,
|
|
27
27
|
paginateBlogPosts,
|
|
@@ -36,49 +36,20 @@ import {createBlogFeedFiles, createFeedHtmlHeadTags} from './feed';
|
|
|
36
36
|
|
|
37
37
|
import {createAllRoutes} from './routes';
|
|
38
38
|
import {checkAuthorsMapPermalinkCollisions, getAuthorsMap} from './authorsMap';
|
|
39
|
+
import {createContentHelpers} from './contentHelpers';
|
|
39
40
|
import type {BlogContentPaths, BlogMarkdownLoaderOptions} from './types';
|
|
40
41
|
import type {LoadContext, Plugin} from '@docusaurus/types';
|
|
41
42
|
import type {
|
|
42
43
|
PluginOptions,
|
|
43
|
-
BlogPostFrontMatter,
|
|
44
|
-
BlogPostMetadata,
|
|
45
44
|
Assets,
|
|
46
45
|
BlogTags,
|
|
47
46
|
BlogContent,
|
|
48
47
|
BlogPaginated,
|
|
49
48
|
} from '@docusaurus/plugin-content-blog';
|
|
50
|
-
import type {
|
|
51
|
-
import type {RuleSetUseItem} from 'webpack';
|
|
49
|
+
import type {RuleSetRule, RuleSetUseItem} from 'webpack';
|
|
52
50
|
|
|
53
51
|
const PluginName = 'docusaurus-plugin-content-blog';
|
|
54
52
|
|
|
55
|
-
// TODO this is bad, we should have a better way to do this (new lifecycle?)
|
|
56
|
-
// The source to permalink is currently a mutable map passed to the mdx loader
|
|
57
|
-
// for link resolution
|
|
58
|
-
// see https://github.com/facebook/docusaurus/pull/10185
|
|
59
|
-
function createSourceToPermalinkHelper() {
|
|
60
|
-
const sourceToPermalink: SourceToPermalink = new Map();
|
|
61
|
-
|
|
62
|
-
function computeSourceToPermalink(content: BlogContent): SourceToPermalink {
|
|
63
|
-
return new Map(
|
|
64
|
-
content.blogPosts.map(({metadata: {source, permalink}}) => [
|
|
65
|
-
source,
|
|
66
|
-
permalink,
|
|
67
|
-
]),
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Mutable map update :/
|
|
72
|
-
function update(content: BlogContent): void {
|
|
73
|
-
sourceToPermalink.clear();
|
|
74
|
-
computeSourceToPermalink(content).forEach((value, key) => {
|
|
75
|
-
sourceToPermalink.set(key, value);
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return {get: () => sourceToPermalink, update};
|
|
80
|
-
}
|
|
81
|
-
|
|
82
53
|
export default async function pluginContentBlog(
|
|
83
54
|
context: LoadContext,
|
|
84
55
|
options: PluginOptions,
|
|
@@ -125,7 +96,99 @@ export default async function pluginContentBlog(
|
|
|
125
96
|
contentPaths,
|
|
126
97
|
});
|
|
127
98
|
|
|
128
|
-
const
|
|
99
|
+
const contentHelpers = createContentHelpers();
|
|
100
|
+
|
|
101
|
+
async function createBlogMDXLoaderRule(): Promise<RuleSetRule> {
|
|
102
|
+
const {
|
|
103
|
+
admonitions,
|
|
104
|
+
rehypePlugins,
|
|
105
|
+
remarkPlugins,
|
|
106
|
+
recmaPlugins,
|
|
107
|
+
truncateMarker,
|
|
108
|
+
beforeDefaultRemarkPlugins,
|
|
109
|
+
beforeDefaultRehypePlugins,
|
|
110
|
+
} = options;
|
|
111
|
+
|
|
112
|
+
const contentDirs = getContentPathList(contentPaths);
|
|
113
|
+
|
|
114
|
+
const mdxLoaderItem = await createMDXLoaderItem({
|
|
115
|
+
useCrossCompilerCache:
|
|
116
|
+
siteConfig.future.experimental_faster.mdxCrossCompilerCache,
|
|
117
|
+
admonitions,
|
|
118
|
+
remarkPlugins,
|
|
119
|
+
rehypePlugins,
|
|
120
|
+
recmaPlugins,
|
|
121
|
+
beforeDefaultRemarkPlugins: [
|
|
122
|
+
footnoteIDFixer,
|
|
123
|
+
...beforeDefaultRemarkPlugins,
|
|
124
|
+
],
|
|
125
|
+
beforeDefaultRehypePlugins,
|
|
126
|
+
staticDirs: siteConfig.staticDirectories.map((dir) =>
|
|
127
|
+
path.resolve(siteDir, dir),
|
|
128
|
+
),
|
|
129
|
+
siteDir,
|
|
130
|
+
isMDXPartial: createAbsoluteFilePathMatcher(options.exclude, contentDirs),
|
|
131
|
+
metadataPath: (mdxPath: string) => {
|
|
132
|
+
// Note that metadataPath must be the same/in-sync as
|
|
133
|
+
// the path from createData for each MDX.
|
|
134
|
+
const aliasedPath = aliasedSitePath(mdxPath, siteDir);
|
|
135
|
+
return path.join(dataDir, `${docuHash(aliasedPath)}.json`);
|
|
136
|
+
},
|
|
137
|
+
// For blog posts a title in markdown is always removed
|
|
138
|
+
// Blog posts title are rendered separately
|
|
139
|
+
removeContentTitle: true,
|
|
140
|
+
// createAssets converts relative paths to require() calls
|
|
141
|
+
createAssets: ({filePath}: {filePath: string}): Assets => {
|
|
142
|
+
const blogPost = contentHelpers.sourceToBlogPost.get(
|
|
143
|
+
aliasedSitePath(filePath, siteDir),
|
|
144
|
+
)!;
|
|
145
|
+
if (!blogPost) {
|
|
146
|
+
throw new Error(`Blog post not found for filePath=${filePath}`);
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
image: blogPost.metadata.frontMatter.image as string,
|
|
150
|
+
authorsImageUrls: blogPost.metadata.authors.map(
|
|
151
|
+
(author) => author.imageURL,
|
|
152
|
+
),
|
|
153
|
+
};
|
|
154
|
+
},
|
|
155
|
+
markdownConfig: siteConfig.markdown,
|
|
156
|
+
resolveMarkdownLink: ({linkPathname, sourceFilePath}) => {
|
|
157
|
+
const permalink = resolveMarkdownLinkPathname(linkPathname, {
|
|
158
|
+
sourceFilePath,
|
|
159
|
+
sourceToPermalink: contentHelpers.sourceToPermalink,
|
|
160
|
+
siteDir,
|
|
161
|
+
contentPaths,
|
|
162
|
+
});
|
|
163
|
+
if (permalink === null) {
|
|
164
|
+
logger.report(
|
|
165
|
+
onBrokenMarkdownLinks,
|
|
166
|
+
)`Blog markdown link couldn't be resolved: (url=${linkPathname}) in source file path=${sourceFilePath}`;
|
|
167
|
+
}
|
|
168
|
+
return permalink;
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
function createBlogMarkdownLoader(): RuleSetUseItem {
|
|
173
|
+
const markdownLoaderOptions: BlogMarkdownLoaderOptions = {
|
|
174
|
+
truncateMarker,
|
|
175
|
+
};
|
|
176
|
+
return {
|
|
177
|
+
loader: path.resolve(__dirname, './markdownLoader.js'),
|
|
178
|
+
options: markdownLoaderOptions,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
test: /\.mdx?$/i,
|
|
184
|
+
include: contentDirs
|
|
185
|
+
// Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
|
|
186
|
+
.map(addTrailingPathSeparator),
|
|
187
|
+
use: [mdxLoaderItem, createBlogMarkdownLoader()],
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const blogMDXLoaderRule = await createBlogMDXLoaderRule();
|
|
129
192
|
|
|
130
193
|
return {
|
|
131
194
|
name: PluginName,
|
|
@@ -177,6 +240,7 @@ export default async function pluginContentBlog(
|
|
|
177
240
|
routeBasePath,
|
|
178
241
|
authorsBasePath,
|
|
179
242
|
]),
|
|
243
|
+
baseUrl,
|
|
180
244
|
});
|
|
181
245
|
checkAuthorsMapPermalinkCollisions(authorsMap);
|
|
182
246
|
|
|
@@ -257,7 +321,7 @@ export default async function pluginContentBlog(
|
|
|
257
321
|
},
|
|
258
322
|
|
|
259
323
|
async contentLoaded({content, actions}) {
|
|
260
|
-
|
|
324
|
+
contentHelpers.updateContent(content);
|
|
261
325
|
|
|
262
326
|
await createAllRoutes({
|
|
263
327
|
baseUrl,
|
|
@@ -273,91 +337,6 @@ export default async function pluginContentBlog(
|
|
|
273
337
|
},
|
|
274
338
|
|
|
275
339
|
configureWebpack() {
|
|
276
|
-
const {
|
|
277
|
-
admonitions,
|
|
278
|
-
rehypePlugins,
|
|
279
|
-
remarkPlugins,
|
|
280
|
-
recmaPlugins,
|
|
281
|
-
truncateMarker,
|
|
282
|
-
beforeDefaultRemarkPlugins,
|
|
283
|
-
beforeDefaultRehypePlugins,
|
|
284
|
-
} = options;
|
|
285
|
-
|
|
286
|
-
const contentDirs = getContentPathList(contentPaths);
|
|
287
|
-
|
|
288
|
-
function createMDXLoader(): RuleSetUseItem {
|
|
289
|
-
const loaderOptions: MDXLoaderOptions = {
|
|
290
|
-
admonitions,
|
|
291
|
-
remarkPlugins,
|
|
292
|
-
rehypePlugins,
|
|
293
|
-
recmaPlugins,
|
|
294
|
-
beforeDefaultRemarkPlugins: [
|
|
295
|
-
footnoteIDFixer,
|
|
296
|
-
...beforeDefaultRemarkPlugins,
|
|
297
|
-
],
|
|
298
|
-
beforeDefaultRehypePlugins,
|
|
299
|
-
staticDirs: siteConfig.staticDirectories.map((dir) =>
|
|
300
|
-
path.resolve(siteDir, dir),
|
|
301
|
-
),
|
|
302
|
-
siteDir,
|
|
303
|
-
isMDXPartial: createAbsoluteFilePathMatcher(
|
|
304
|
-
options.exclude,
|
|
305
|
-
contentDirs,
|
|
306
|
-
),
|
|
307
|
-
metadataPath: (mdxPath: string) => {
|
|
308
|
-
// Note that metadataPath must be the same/in-sync as
|
|
309
|
-
// the path from createData for each MDX.
|
|
310
|
-
const aliasedPath = aliasedSitePath(mdxPath, siteDir);
|
|
311
|
-
return path.join(dataDir, `${docuHash(aliasedPath)}.json`);
|
|
312
|
-
},
|
|
313
|
-
// For blog posts a title in markdown is always removed
|
|
314
|
-
// Blog posts title are rendered separately
|
|
315
|
-
removeContentTitle: true,
|
|
316
|
-
// Assets allow to convert some relative images paths to
|
|
317
|
-
// require() calls
|
|
318
|
-
// @ts-expect-error: TODO fix typing issue
|
|
319
|
-
createAssets: ({
|
|
320
|
-
frontMatter,
|
|
321
|
-
metadata,
|
|
322
|
-
}: {
|
|
323
|
-
frontMatter: BlogPostFrontMatter;
|
|
324
|
-
metadata: BlogPostMetadata;
|
|
325
|
-
}): Assets => ({
|
|
326
|
-
image: frontMatter.image,
|
|
327
|
-
authorsImageUrls: metadata.authors.map((author) => author.imageURL),
|
|
328
|
-
}),
|
|
329
|
-
markdownConfig: siteConfig.markdown,
|
|
330
|
-
resolveMarkdownLink: ({linkPathname, sourceFilePath}) => {
|
|
331
|
-
const permalink = resolveMarkdownLinkPathname(linkPathname, {
|
|
332
|
-
sourceFilePath,
|
|
333
|
-
sourceToPermalink: sourceToPermalinkHelper.get(),
|
|
334
|
-
siteDir,
|
|
335
|
-
contentPaths,
|
|
336
|
-
});
|
|
337
|
-
if (permalink === null) {
|
|
338
|
-
logger.report(
|
|
339
|
-
onBrokenMarkdownLinks,
|
|
340
|
-
)`Blog markdown link couldn't be resolved: (url=${linkPathname}) in source file path=${sourceFilePath}`;
|
|
341
|
-
}
|
|
342
|
-
return permalink;
|
|
343
|
-
},
|
|
344
|
-
};
|
|
345
|
-
return {
|
|
346
|
-
loader: require.resolve('@docusaurus/mdx-loader'),
|
|
347
|
-
options: loaderOptions,
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
function createBlogMarkdownLoader(): RuleSetUseItem {
|
|
352
|
-
const loaderOptions: BlogMarkdownLoaderOptions = {
|
|
353
|
-
truncateMarker,
|
|
354
|
-
};
|
|
355
|
-
return {
|
|
356
|
-
loader: path.resolve(__dirname, './markdownLoader.js'),
|
|
357
|
-
options: loaderOptions,
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
|
|
361
340
|
return {
|
|
362
341
|
resolve: {
|
|
363
342
|
alias: {
|
|
@@ -365,15 +344,7 @@ export default async function pluginContentBlog(
|
|
|
365
344
|
},
|
|
366
345
|
},
|
|
367
346
|
module: {
|
|
368
|
-
rules: [
|
|
369
|
-
{
|
|
370
|
-
test: /\.mdx?$/i,
|
|
371
|
-
include: contentDirs
|
|
372
|
-
// Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
|
|
373
|
-
.map(addTrailingPathSeparator),
|
|
374
|
-
use: [createMDXLoader(), createBlogMarkdownLoader()],
|
|
375
|
-
},
|
|
376
|
-
],
|
|
347
|
+
rules: [blogMDXLoaderRule],
|
|
377
348
|
},
|
|
378
349
|
};
|
|
379
350
|
},
|
package/src/options.ts
CHANGED
|
@@ -68,9 +68,9 @@ export const DEFAULT_OPTIONS: PluginOptions = {
|
|
|
68
68
|
showLastUpdateTime: false,
|
|
69
69
|
showLastUpdateAuthor: false,
|
|
70
70
|
processBlogPosts: async () => undefined,
|
|
71
|
-
onInlineTags: 'warn',
|
|
72
71
|
tags: undefined,
|
|
73
72
|
authorsBasePath: 'authors',
|
|
73
|
+
onInlineTags: 'warn',
|
|
74
74
|
onInlineAuthors: 'warn',
|
|
75
75
|
onUntruncatedBlogPosts: 'warn',
|
|
76
76
|
};
|