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