@docusaurus/plugin-content-blog 2.0.0-beta.2 → 2.0.0-beta.20
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 +22 -0
- package/lib/authors.js +118 -0
- package/lib/blogUtils.d.ts +27 -7
- package/lib/blogUtils.js +201 -145
- package/lib/feed.d.ts +15 -0
- package/lib/feed.js +100 -0
- package/lib/frontMatter.d.ts +10 -0
- package/lib/{blogFrontMatter.js → frontMatter.js} +31 -19
- package/lib/index.d.ts +4 -4
- package/lib/index.js +165 -185
- package/lib/markdownLoader.d.ts +3 -6
- package/lib/markdownLoader.js +6 -7
- package/lib/options.d.ts +10 -0
- package/lib/{pluginOptionSchema.js → options.js} +43 -13
- package/lib/remark/footnoteIDFixer.d.ts +14 -0
- package/lib/remark/footnoteIDFixer.js +29 -0
- package/lib/translations.d.ts +10 -0
- package/lib/translations.js +53 -0
- package/lib/types.d.ts +4 -109
- package/package.json +22 -18
- package/src/authors.ts +164 -0
- package/src/blogUtils.ts +306 -204
- package/{types.d.ts → src/deps.d.ts} +1 -1
- package/src/feed.ts +169 -0
- package/src/frontMatter.ts +81 -0
- package/src/index.ts +225 -246
- package/src/markdownLoader.ts +11 -16
- package/src/{pluginOptionSchema.ts → options.ts} +54 -14
- package/src/plugin-content-blog.d.ts +580 -0
- package/src/remark/footnoteIDFixer.ts +29 -0
- package/src/translations.ts +69 -0
- package/src/types.ts +2 -128
- package/index.d.ts +0 -138
- package/lib/.tsbuildinfo +0 -1
- package/lib/blogFrontMatter.d.ts +0 -28
- package/lib/pluginOptionSchema.d.ts +0 -33
- 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/src/blogFrontMatter.ts +0 -88
- package/tsconfig.json +0 -9
package/lib/index.js
CHANGED
|
@@ -8,60 +8,62 @@
|
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.validateOptions = void 0;
|
|
10
10
|
const tslib_1 = require("tslib");
|
|
11
|
-
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
12
11
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
13
12
|
const remark_admonitions_1 = tslib_1.__importDefault(require("remark-admonitions"));
|
|
13
|
+
const footnoteIDFixer_1 = tslib_1.__importDefault(require("./remark/footnoteIDFixer"));
|
|
14
14
|
const utils_1 = require("@docusaurus/utils");
|
|
15
|
-
const
|
|
16
|
-
const lodash_1 = require("lodash");
|
|
17
|
-
const pluginOptionSchema_1 = require("./pluginOptionSchema");
|
|
15
|
+
const translations_1 = require("./translations");
|
|
18
16
|
const blogUtils_1 = require("./blogUtils");
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
const feed_1 = require("./feed");
|
|
18
|
+
async function pluginContentBlog(context, options) {
|
|
21
19
|
if (options.admonitions) {
|
|
22
20
|
options.remarkPlugins = options.remarkPlugins.concat([
|
|
23
21
|
[remark_admonitions_1.default, options.admonitions],
|
|
24
22
|
]);
|
|
25
23
|
}
|
|
26
|
-
const { siteDir, siteConfig
|
|
24
|
+
const { siteDir, siteConfig, generatedFilesDir, i18n: { currentLocale }, } = context;
|
|
25
|
+
const { onBrokenMarkdownLinks, baseUrl } = siteConfig;
|
|
27
26
|
const contentPaths = {
|
|
28
27
|
contentPath: path_1.default.resolve(siteDir, options.path),
|
|
29
|
-
contentPathLocalized: utils_1.getPluginI18nPath({
|
|
28
|
+
contentPathLocalized: (0, utils_1.getPluginI18nPath)({
|
|
30
29
|
siteDir,
|
|
31
30
|
locale: currentLocale,
|
|
32
31
|
pluginName: 'docusaurus-plugin-content-blog',
|
|
33
32
|
pluginId: options.id,
|
|
34
33
|
}),
|
|
35
34
|
};
|
|
36
|
-
const pluginId =
|
|
35
|
+
const pluginId = options.id ?? utils_1.DEFAULT_PLUGIN_ID;
|
|
37
36
|
const pluginDataDirRoot = path_1.default.join(generatedFilesDir, 'docusaurus-plugin-content-blog');
|
|
38
37
|
const dataDir = path_1.default.join(pluginDataDirRoot, pluginId);
|
|
39
|
-
const aliasedSource = (source) => `~blog/${utils_1.posixPath(path_1.default.relative(pluginDataDirRoot, source))}`;
|
|
38
|
+
const aliasedSource = (source) => `~blog/${(0, utils_1.posixPath)(path_1.default.relative(pluginDataDirRoot, source))}`;
|
|
39
|
+
const authorsMapFilePath = await (0, utils_1.getDataFilePath)({
|
|
40
|
+
filePath: options.authorsMapPath,
|
|
41
|
+
contentPaths,
|
|
42
|
+
});
|
|
40
43
|
return {
|
|
41
44
|
name: 'docusaurus-plugin-content-blog',
|
|
42
45
|
getPathsToWatch() {
|
|
43
|
-
const { include
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}));
|
|
46
|
+
const { include } = options;
|
|
47
|
+
const contentMarkdownGlobs = (0, utils_1.getContentPathList)(contentPaths).flatMap((contentPath) => include.map((pattern) => `${contentPath}/${pattern}`));
|
|
48
|
+
return [authorsMapFilePath, ...contentMarkdownGlobs].filter(Boolean);
|
|
47
49
|
},
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (options.admonitions) {
|
|
51
|
-
modules.push(require.resolve('remark-admonitions/styles/infima.css'));
|
|
52
|
-
}
|
|
53
|
-
return modules;
|
|
50
|
+
getTranslationFiles() {
|
|
51
|
+
return (0, translations_1.getTranslationFiles)(options);
|
|
54
52
|
},
|
|
55
53
|
// Fetches blog contents and returns metadata for the necessary routes.
|
|
56
54
|
async loadContent() {
|
|
57
|
-
const { postsPerPage, routeBasePath } = options;
|
|
58
|
-
const
|
|
55
|
+
const { postsPerPage: postsPerPageOption, routeBasePath, tagsBasePath, blogDescription, blogTitle, blogSidebarTitle, } = options;
|
|
56
|
+
const baseBlogUrl = (0, utils_1.normalizeUrl)([baseUrl, routeBasePath]);
|
|
57
|
+
const blogTagsListPath = (0, utils_1.normalizeUrl)([baseBlogUrl, tagsBasePath]);
|
|
58
|
+
const blogPosts = await (0, blogUtils_1.generateBlogPosts)(contentPaths, context, options);
|
|
59
59
|
if (!blogPosts.length) {
|
|
60
60
|
return {
|
|
61
|
+
blogSidebarTitle,
|
|
61
62
|
blogPosts: [],
|
|
62
63
|
blogListPaginated: [],
|
|
63
64
|
blogTags: {},
|
|
64
|
-
blogTagsListPath
|
|
65
|
+
blogTagsListPath,
|
|
66
|
+
blogTagsPaginated: [],
|
|
65
67
|
};
|
|
66
68
|
}
|
|
67
69
|
// Colocate next and prev metadata.
|
|
@@ -81,72 +83,21 @@ function pluginContentBlog(context, options) {
|
|
|
81
83
|
};
|
|
82
84
|
}
|
|
83
85
|
});
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
for (let page = 0; page < numberOfPages; page += 1) {
|
|
97
|
-
blogListPaginated.push({
|
|
98
|
-
metadata: {
|
|
99
|
-
permalink: blogPaginationPermalink(page),
|
|
100
|
-
page: page + 1,
|
|
101
|
-
postsPerPage,
|
|
102
|
-
totalPages: numberOfPages,
|
|
103
|
-
totalCount,
|
|
104
|
-
previousPage: page !== 0 ? blogPaginationPermalink(page - 1) : null,
|
|
105
|
-
nextPage: page < numberOfPages - 1
|
|
106
|
-
? blogPaginationPermalink(page + 1)
|
|
107
|
-
: null,
|
|
108
|
-
blogDescription: options.blogDescription,
|
|
109
|
-
blogTitle: options.blogTitle,
|
|
110
|
-
},
|
|
111
|
-
items: blogPosts
|
|
112
|
-
.slice(page * postsPerPage, (page + 1) * postsPerPage)
|
|
113
|
-
.map((item) => item.id),
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
const blogTags = {};
|
|
117
|
-
const tagsPath = utils_1.normalizeUrl([basePageUrl, 'tags']);
|
|
118
|
-
blogPosts.forEach((blogPost) => {
|
|
119
|
-
const { tags } = blogPost.metadata;
|
|
120
|
-
if (!tags || tags.length === 0) {
|
|
121
|
-
// TODO: Extract tags out into a separate plugin.
|
|
122
|
-
// eslint-disable-next-line no-param-reassign
|
|
123
|
-
blogPost.metadata.tags = [];
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
// eslint-disable-next-line no-param-reassign
|
|
127
|
-
blogPost.metadata.tags = tags.map((tag) => {
|
|
128
|
-
if (typeof tag === 'string') {
|
|
129
|
-
const normalizedTag = lodash_1.kebabCase(tag);
|
|
130
|
-
const permalink = utils_1.normalizeUrl([tagsPath, normalizedTag]);
|
|
131
|
-
if (!blogTags[normalizedTag]) {
|
|
132
|
-
blogTags[normalizedTag] = {
|
|
133
|
-
// Will only use the name of the first occurrence of the tag.
|
|
134
|
-
name: tag.toLowerCase(),
|
|
135
|
-
items: [],
|
|
136
|
-
permalink,
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
blogTags[normalizedTag].items.push(blogPost.id);
|
|
140
|
-
return {
|
|
141
|
-
label: tag,
|
|
142
|
-
permalink,
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
return tag;
|
|
146
|
-
});
|
|
86
|
+
const blogListPaginated = (0, blogUtils_1.paginateBlogPosts)({
|
|
87
|
+
blogPosts,
|
|
88
|
+
blogTitle,
|
|
89
|
+
blogDescription,
|
|
90
|
+
postsPerPageOption,
|
|
91
|
+
basePageUrl: baseBlogUrl,
|
|
92
|
+
});
|
|
93
|
+
const blogTags = (0, blogUtils_1.getBlogTags)({
|
|
94
|
+
blogPosts,
|
|
95
|
+
postsPerPageOption,
|
|
96
|
+
blogDescription,
|
|
97
|
+
blogTitle,
|
|
147
98
|
});
|
|
148
|
-
const blogTagsListPath = Object.keys(blogTags).length > 0 ? tagsPath : null;
|
|
149
99
|
return {
|
|
100
|
+
blogSidebarTitle,
|
|
150
101
|
blogPosts,
|
|
151
102
|
blogListPaginated,
|
|
152
103
|
blogTags,
|
|
@@ -157,19 +108,36 @@ function pluginContentBlog(context, options) {
|
|
|
157
108
|
if (!blogContents) {
|
|
158
109
|
return;
|
|
159
110
|
}
|
|
160
|
-
const { blogListComponent, blogPostComponent, blogTagsListComponent, blogTagsPostsComponent, } = options;
|
|
111
|
+
const { blogListComponent, blogPostComponent, blogTagsListComponent, blogTagsPostsComponent, blogArchiveComponent, routeBasePath, archiveBasePath, } = options;
|
|
161
112
|
const { addRoute, createData } = actions;
|
|
162
|
-
const { blogPosts, blogListPaginated, blogTags, blogTagsListPath, } = blogContents;
|
|
113
|
+
const { blogSidebarTitle, blogPosts, blogListPaginated, blogTags, blogTagsListPath, } = blogContents;
|
|
163
114
|
const blogItemsToMetadata = {};
|
|
164
115
|
const sidebarBlogPosts = options.blogSidebarCount === 'ALL'
|
|
165
116
|
? blogPosts
|
|
166
|
-
:
|
|
117
|
+
: blogPosts.slice(0, options.blogSidebarCount);
|
|
118
|
+
if (archiveBasePath && blogPosts.length) {
|
|
119
|
+
const archiveUrl = (0, utils_1.normalizeUrl)([
|
|
120
|
+
baseUrl,
|
|
121
|
+
routeBasePath,
|
|
122
|
+
archiveBasePath,
|
|
123
|
+
]);
|
|
124
|
+
// Create a blog archive route
|
|
125
|
+
const archiveProp = await createData(`${(0, utils_1.docuHash)(archiveUrl)}.json`, JSON.stringify({ blogPosts }, null, 2));
|
|
126
|
+
addRoute({
|
|
127
|
+
path: archiveUrl,
|
|
128
|
+
component: blogArchiveComponent,
|
|
129
|
+
exact: true,
|
|
130
|
+
modules: {
|
|
131
|
+
archive: aliasedSource(archiveProp),
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
}
|
|
167
135
|
// This prop is useful to provide the blog list sidebar
|
|
168
136
|
const sidebarProp = await createData(
|
|
169
137
|
// Note that this created data path must be in sync with
|
|
170
138
|
// metadataPath provided to mdx-loader.
|
|
171
139
|
`blog-post-list-prop-${pluginId}.json`, JSON.stringify({
|
|
172
|
-
title:
|
|
140
|
+
title: blogSidebarTitle,
|
|
173
141
|
items: sidebarBlogPosts.map((blogPost) => ({
|
|
174
142
|
title: blogPost.metadata.title,
|
|
175
143
|
permalink: blogPost.metadata.permalink,
|
|
@@ -181,7 +149,7 @@ function pluginContentBlog(context, options) {
|
|
|
181
149
|
await createData(
|
|
182
150
|
// Note that this created data path must be in sync with
|
|
183
151
|
// metadataPath provided to mdx-loader.
|
|
184
|
-
`${utils_1.docuHash(metadata.source)}.json`, JSON.stringify(metadata, null, 2));
|
|
152
|
+
`${(0, utils_1.docuHash)(metadata.source)}.json`, JSON.stringify(metadata, null, 2));
|
|
185
153
|
addRoute({
|
|
186
154
|
path: metadata.permalink,
|
|
187
155
|
component: blogPostComponent,
|
|
@@ -197,79 +165,87 @@ function pluginContentBlog(context, options) {
|
|
|
197
165
|
await Promise.all(blogListPaginated.map(async (listPage) => {
|
|
198
166
|
const { metadata, items } = listPage;
|
|
199
167
|
const { permalink } = metadata;
|
|
200
|
-
const pageMetadataPath = await createData(`${utils_1.docuHash(permalink)}.json`, JSON.stringify(metadata, null, 2));
|
|
168
|
+
const pageMetadataPath = await createData(`${(0, utils_1.docuHash)(permalink)}.json`, JSON.stringify(metadata, null, 2));
|
|
201
169
|
addRoute({
|
|
202
170
|
path: permalink,
|
|
203
171
|
component: blogListComponent,
|
|
204
172
|
exact: true,
|
|
205
173
|
modules: {
|
|
206
174
|
sidebar: aliasedSource(sidebarProp),
|
|
207
|
-
items: items.map((postID) => {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
query: {
|
|
214
|
-
truncated: true,
|
|
215
|
-
},
|
|
175
|
+
items: items.map((postID) => ({
|
|
176
|
+
content: {
|
|
177
|
+
__import: true,
|
|
178
|
+
path: blogItemsToMetadata[postID].source,
|
|
179
|
+
query: {
|
|
180
|
+
truncated: true,
|
|
216
181
|
},
|
|
217
|
-
}
|
|
218
|
-
}),
|
|
182
|
+
},
|
|
183
|
+
})),
|
|
219
184
|
metadata: aliasedSource(pageMetadataPath),
|
|
220
185
|
},
|
|
221
186
|
});
|
|
222
187
|
}));
|
|
223
|
-
// Tags.
|
|
224
|
-
if (
|
|
188
|
+
// Tags. This is the last part so we early-return if there are no tags.
|
|
189
|
+
if (Object.keys(blogTags).length === 0) {
|
|
225
190
|
return;
|
|
226
191
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
count: items.length,
|
|
235
|
-
permalink,
|
|
236
|
-
};
|
|
237
|
-
const tagsMetadataPath = await createData(`${utils_1.docuHash(permalink)}.json`, JSON.stringify(tagsModule[tag], null, 2));
|
|
238
|
-
addRoute({
|
|
239
|
-
path: permalink,
|
|
240
|
-
component: blogTagsPostsComponent,
|
|
241
|
-
exact: true,
|
|
242
|
-
modules: {
|
|
243
|
-
sidebar: aliasedSource(sidebarProp),
|
|
244
|
-
items: items.map((postID) => {
|
|
245
|
-
const metadata = blogItemsToMetadata[postID];
|
|
246
|
-
return {
|
|
247
|
-
content: {
|
|
248
|
-
__import: true,
|
|
249
|
-
path: metadata.source,
|
|
250
|
-
query: {
|
|
251
|
-
truncated: true,
|
|
252
|
-
},
|
|
253
|
-
},
|
|
254
|
-
};
|
|
255
|
-
}),
|
|
256
|
-
metadata: aliasedSource(tagsMetadataPath),
|
|
257
|
-
},
|
|
258
|
-
});
|
|
259
|
-
}));
|
|
260
|
-
// Only create /tags page if there are tags.
|
|
261
|
-
if (Object.keys(blogTags).length > 0) {
|
|
262
|
-
const tagsListPath = await createData(`${utils_1.docuHash(`${blogTagsListPath}-tags`)}.json`, JSON.stringify(tagsModule, null, 2));
|
|
192
|
+
async function createTagsListPage() {
|
|
193
|
+
const tagsProp = Object.values(blogTags).map((tag) => ({
|
|
194
|
+
label: tag.label,
|
|
195
|
+
permalink: tag.permalink,
|
|
196
|
+
count: tag.items.length,
|
|
197
|
+
}));
|
|
198
|
+
const tagsPropPath = await createData(`${(0, utils_1.docuHash)(`${blogTagsListPath}-tags`)}.json`, JSON.stringify(tagsProp, null, 2));
|
|
263
199
|
addRoute({
|
|
264
200
|
path: blogTagsListPath,
|
|
265
201
|
component: blogTagsListComponent,
|
|
266
202
|
exact: true,
|
|
267
203
|
modules: {
|
|
268
204
|
sidebar: aliasedSource(sidebarProp),
|
|
269
|
-
tags: aliasedSource(
|
|
205
|
+
tags: aliasedSource(tagsPropPath),
|
|
270
206
|
},
|
|
271
207
|
});
|
|
272
208
|
}
|
|
209
|
+
async function createTagPostsListPage(tag) {
|
|
210
|
+
await Promise.all(tag.pages.map(async (blogPaginated) => {
|
|
211
|
+
const { metadata, items } = blogPaginated;
|
|
212
|
+
const tagProp = {
|
|
213
|
+
label: tag.label,
|
|
214
|
+
permalink: tag.permalink,
|
|
215
|
+
allTagsPath: blogTagsListPath,
|
|
216
|
+
count: tag.items.length,
|
|
217
|
+
};
|
|
218
|
+
const tagPropPath = await createData(`${(0, utils_1.docuHash)(metadata.permalink)}.json`, JSON.stringify(tagProp, null, 2));
|
|
219
|
+
const listMetadataPath = await createData(`${(0, utils_1.docuHash)(metadata.permalink)}-list.json`, JSON.stringify(metadata, null, 2));
|
|
220
|
+
addRoute({
|
|
221
|
+
path: metadata.permalink,
|
|
222
|
+
component: blogTagsPostsComponent,
|
|
223
|
+
exact: true,
|
|
224
|
+
modules: {
|
|
225
|
+
sidebar: aliasedSource(sidebarProp),
|
|
226
|
+
items: items.map((postID) => {
|
|
227
|
+
const blogPostMetadata = blogItemsToMetadata[postID];
|
|
228
|
+
return {
|
|
229
|
+
content: {
|
|
230
|
+
__import: true,
|
|
231
|
+
path: blogPostMetadata.source,
|
|
232
|
+
query: {
|
|
233
|
+
truncated: true,
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
}),
|
|
238
|
+
tag: aliasedSource(tagPropPath),
|
|
239
|
+
listMetadata: aliasedSource(listMetadataPath),
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
}));
|
|
243
|
+
}
|
|
244
|
+
await createTagsListPage();
|
|
245
|
+
await Promise.all(Object.values(blogTags).map(createTagPostsListPage));
|
|
246
|
+
},
|
|
247
|
+
translateContent({ content, translationFiles }) {
|
|
248
|
+
return (0, translations_1.translateContent)(content, translationFiles);
|
|
273
249
|
},
|
|
274
250
|
configureWebpack(_config, isServer, { getJSLoader }, content) {
|
|
275
251
|
const { rehypePlugins, remarkPlugins, truncateMarker, beforeDefaultRemarkPlugins, beforeDefaultRehypePlugins, } = options;
|
|
@@ -277,14 +253,15 @@ function pluginContentBlog(context, options) {
|
|
|
277
253
|
siteDir,
|
|
278
254
|
contentPaths,
|
|
279
255
|
truncateMarker,
|
|
280
|
-
sourceToPermalink: blogUtils_1.getSourceToPermalink(content.blogPosts),
|
|
256
|
+
sourceToPermalink: (0, blogUtils_1.getSourceToPermalink)(content.blogPosts),
|
|
281
257
|
onBrokenMarkdownLink: (brokenMarkdownLink) => {
|
|
282
258
|
if (onBrokenMarkdownLinks === 'ignore') {
|
|
283
259
|
return;
|
|
284
260
|
}
|
|
285
|
-
utils_1.reportMessage(`Blog markdown link couldn't be resolved: (${brokenMarkdownLink.link}) in ${brokenMarkdownLink.filePath}`, onBrokenMarkdownLinks);
|
|
261
|
+
(0, utils_1.reportMessage)(`Blog markdown link couldn't be resolved: (${brokenMarkdownLink.link}) in ${brokenMarkdownLink.filePath}`, onBrokenMarkdownLinks);
|
|
286
262
|
},
|
|
287
263
|
};
|
|
264
|
+
const contentDirs = (0, utils_1.getContentPathList)(contentPaths);
|
|
288
265
|
return {
|
|
289
266
|
resolve: {
|
|
290
267
|
alias: {
|
|
@@ -294,8 +271,8 @@ function pluginContentBlog(context, options) {
|
|
|
294
271
|
module: {
|
|
295
272
|
rules: [
|
|
296
273
|
{
|
|
297
|
-
test:
|
|
298
|
-
include:
|
|
274
|
+
test: /\.mdx?$/i,
|
|
275
|
+
include: contentDirs
|
|
299
276
|
// Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
|
|
300
277
|
.map(utils_1.addTrailingPathSeparator),
|
|
301
278
|
use: [
|
|
@@ -305,18 +282,29 @@ function pluginContentBlog(context, options) {
|
|
|
305
282
|
options: {
|
|
306
283
|
remarkPlugins,
|
|
307
284
|
rehypePlugins,
|
|
308
|
-
beforeDefaultRemarkPlugins
|
|
285
|
+
beforeDefaultRemarkPlugins: [
|
|
286
|
+
footnoteIDFixer_1.default,
|
|
287
|
+
...beforeDefaultRemarkPlugins,
|
|
288
|
+
],
|
|
309
289
|
beforeDefaultRehypePlugins,
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
290
|
+
staticDirs: siteConfig.staticDirectories.map((dir) => path_1.default.resolve(siteDir, dir)),
|
|
291
|
+
siteDir,
|
|
292
|
+
isMDXPartial: (0, utils_1.createAbsoluteFilePathMatcher)(options.exclude, contentDirs),
|
|
313
293
|
metadataPath: (mdxPath) => {
|
|
314
|
-
|
|
315
|
-
|
|
294
|
+
// Note that metadataPath must be the same/in-sync as
|
|
295
|
+
// the path from createData for each MDX.
|
|
296
|
+
const aliasedPath = (0, utils_1.aliasedSitePath)(mdxPath, siteDir);
|
|
297
|
+
return path_1.default.join(dataDir, `${(0, utils_1.docuHash)(aliasedPath)}.json`);
|
|
316
298
|
},
|
|
317
299
|
// For blog posts a title in markdown is always removed
|
|
318
300
|
// Blog posts title are rendered separately
|
|
319
301
|
removeContentTitle: true,
|
|
302
|
+
// Assets allow to convert some relative images paths to
|
|
303
|
+
// require() calls
|
|
304
|
+
createAssets: ({ frontMatter, metadata, }) => ({
|
|
305
|
+
image: frontMatter.image,
|
|
306
|
+
authorsImageUrls: metadata.authors.map((author) => author.imageURL),
|
|
307
|
+
}),
|
|
320
308
|
},
|
|
321
309
|
},
|
|
322
310
|
{
|
|
@@ -329,62 +317,57 @@ function pluginContentBlog(context, options) {
|
|
|
329
317
|
},
|
|
330
318
|
};
|
|
331
319
|
},
|
|
332
|
-
async postBuild({ outDir }) {
|
|
333
|
-
|
|
334
|
-
if (!((_a = options.feedOptions) === null || _a === void 0 ? void 0 : _a.type)) {
|
|
320
|
+
async postBuild({ outDir, content }) {
|
|
321
|
+
if (!options.feedOptions.type) {
|
|
335
322
|
return;
|
|
336
323
|
}
|
|
337
|
-
const
|
|
338
|
-
if (!
|
|
324
|
+
const { blogPosts } = content;
|
|
325
|
+
if (!blogPosts.length) {
|
|
339
326
|
return;
|
|
340
327
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
catch (err) {
|
|
349
|
-
throw new Error(`Generating ${feedType} feed failed: ${err}.`);
|
|
350
|
-
}
|
|
351
|
-
}));
|
|
328
|
+
await (0, feed_1.createBlogFeedFiles)({
|
|
329
|
+
blogPosts,
|
|
330
|
+
options,
|
|
331
|
+
outDir,
|
|
332
|
+
siteConfig,
|
|
333
|
+
locale: currentLocale,
|
|
334
|
+
});
|
|
352
335
|
},
|
|
353
336
|
injectHtmlTags({ content }) {
|
|
354
|
-
var _a;
|
|
355
337
|
if (!content.blogPosts.length) {
|
|
356
338
|
return {};
|
|
357
339
|
}
|
|
358
|
-
if (!
|
|
340
|
+
if (!options.feedOptions?.type) {
|
|
359
341
|
return {};
|
|
360
342
|
}
|
|
361
343
|
const feedTypes = options.feedOptions.type;
|
|
362
|
-
const
|
|
344
|
+
const feedTitle = options.feedOptions.title ?? context.siteConfig.title;
|
|
363
345
|
const feedsConfig = {
|
|
364
346
|
rss: {
|
|
365
347
|
type: 'application/rss+xml',
|
|
366
348
|
path: 'rss.xml',
|
|
367
|
-
title: `${
|
|
349
|
+
title: `${feedTitle} RSS Feed`,
|
|
368
350
|
},
|
|
369
351
|
atom: {
|
|
370
352
|
type: 'application/atom+xml',
|
|
371
353
|
path: 'atom.xml',
|
|
372
|
-
title: `${
|
|
354
|
+
title: `${feedTitle} Atom Feed`,
|
|
355
|
+
},
|
|
356
|
+
json: {
|
|
357
|
+
type: 'application/json',
|
|
358
|
+
path: 'feed.json',
|
|
359
|
+
title: `${feedTitle} JSON Feed`,
|
|
373
360
|
},
|
|
374
361
|
};
|
|
375
362
|
const headTags = [];
|
|
376
363
|
feedTypes.forEach((feedType) => {
|
|
377
|
-
const
|
|
378
|
-
if (!feedsConfig) {
|
|
379
|
-
return;
|
|
380
|
-
}
|
|
381
|
-
const { type, path: feedConfigPath, title: feedConfigTitle } = feedConfig;
|
|
364
|
+
const { type, path: feedConfigPath, title: feedConfigTitle, } = feedsConfig[feedType];
|
|
382
365
|
headTags.push({
|
|
383
366
|
tagName: 'link',
|
|
384
367
|
attributes: {
|
|
385
368
|
rel: 'alternate',
|
|
386
369
|
type,
|
|
387
|
-
href: utils_1.normalizeUrl([
|
|
370
|
+
href: (0, utils_1.normalizeUrl)([
|
|
388
371
|
baseUrl,
|
|
389
372
|
options.routeBasePath,
|
|
390
373
|
feedConfigPath,
|
|
@@ -400,8 +383,5 @@ function pluginContentBlog(context, options) {
|
|
|
400
383
|
};
|
|
401
384
|
}
|
|
402
385
|
exports.default = pluginContentBlog;
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
return validatedOptions;
|
|
406
|
-
}
|
|
407
|
-
exports.validateOptions = validateOptions;
|
|
386
|
+
var options_1 = require("./options");
|
|
387
|
+
Object.defineProperty(exports, "validateOptions", { enumerable: true, get: function () { return options_1.validateOptions; } });
|
package/lib/markdownLoader.d.ts
CHANGED
|
@@ -4,9 +4,6 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
declare const markdownLoader: Loader;
|
|
12
|
-
export default markdownLoader;
|
|
7
|
+
import type { BlogMarkdownLoaderOptions } from './types';
|
|
8
|
+
import type { LoaderContext } from 'webpack';
|
|
9
|
+
export default function markdownLoader(this: LoaderContext<BlogMarkdownLoaderOptions>, source: string): void;
|
package/lib/markdownLoader.js
CHANGED
|
@@ -7,25 +7,24 @@
|
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
const blogUtils_1 = require("./blogUtils");
|
|
10
|
-
|
|
11
|
-
const markdownLoader = function (source) {
|
|
10
|
+
function markdownLoader(source) {
|
|
12
11
|
const filePath = this.resourcePath;
|
|
13
12
|
const fileString = source;
|
|
14
13
|
const callback = this.async();
|
|
15
14
|
const markdownLoaderOptions = this.getOptions();
|
|
16
15
|
// Linkify blog posts
|
|
17
|
-
let finalContent = blogUtils_1.linkify({
|
|
16
|
+
let finalContent = (0, blogUtils_1.linkify)({
|
|
18
17
|
fileString,
|
|
19
18
|
filePath,
|
|
20
19
|
...markdownLoaderOptions,
|
|
21
20
|
});
|
|
22
21
|
// Truncate content if requested (e.g: file.md?truncated=true).
|
|
23
22
|
const truncated = this.resourceQuery
|
|
24
|
-
? !!
|
|
23
|
+
? !!new URLSearchParams(this.resourceQuery.slice(1)).get('truncated')
|
|
25
24
|
: undefined;
|
|
26
25
|
if (truncated) {
|
|
27
|
-
finalContent = blogUtils_1.truncate(finalContent, markdownLoaderOptions.truncateMarker);
|
|
26
|
+
finalContent = (0, blogUtils_1.truncate)(finalContent, markdownLoaderOptions.truncateMarker);
|
|
28
27
|
}
|
|
29
|
-
return callback
|
|
30
|
-
}
|
|
28
|
+
return callback?.(null, finalContent);
|
|
29
|
+
}
|
|
31
30
|
exports.default = markdownLoader;
|
package/lib/options.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
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 { PluginOptions, Options } from '@docusaurus/plugin-content-blog';
|
|
8
|
+
import type { OptionValidationContext } from '@docusaurus/types';
|
|
9
|
+
export declare const DEFAULT_OPTIONS: PluginOptions;
|
|
10
|
+
export declare function validateOptions({ validate, options, }: OptionValidationContext<Options, PluginOptions>): PluginOptions;
|