@docusaurus/plugin-content-blog 2.0.0-beta.1ec2c95e3 → 2.0.0-beta.21
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 +166 -192
- 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 +168 -0
- package/src/blogUtils.ts +306 -204
- package/{types.d.ts → src/deps.d.ts} +1 -1
- package/src/feed.ts +171 -0
- package/src/frontMatter.ts +81 -0
- package/src/index.ts +227 -256
- package/src/markdownLoader.ts +11 -16
- package/src/{pluginOptionSchema.ts → options.ts} +56 -15
- 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
|
-
const remark_admonitions_1 = tslib_1.__importDefault(require("remark-admonitions"));
|
|
14
12
|
const utils_1 = require("@docusaurus/utils");
|
|
15
|
-
const
|
|
16
|
-
const lodash_1 = require("lodash");
|
|
17
|
-
const pluginOptionSchema_1 = require("./pluginOptionSchema");
|
|
13
|
+
const remark_admonitions_1 = tslib_1.__importDefault(require("remark-admonitions"));
|
|
18
14
|
const blogUtils_1 = require("./blogUtils");
|
|
19
|
-
|
|
20
|
-
|
|
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) {
|
|
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,
|
|
@@ -154,22 +105,36 @@ function pluginContentBlog(context, options) {
|
|
|
154
105
|
};
|
|
155
106
|
},
|
|
156
107
|
async contentLoaded({ content: blogContents, actions }) {
|
|
157
|
-
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
const { blogListComponent, blogPostComponent, blogTagsListComponent, blogTagsPostsComponent, } = options;
|
|
108
|
+
const { blogListComponent, blogPostComponent, blogTagsListComponent, blogTagsPostsComponent, blogArchiveComponent, routeBasePath, archiveBasePath, } = options;
|
|
161
109
|
const { addRoute, createData } = actions;
|
|
162
|
-
const { blogPosts, blogListPaginated, blogTags, blogTagsListPath, } = blogContents;
|
|
110
|
+
const { blogSidebarTitle, blogPosts, blogListPaginated, blogTags, blogTagsListPath, } = blogContents;
|
|
163
111
|
const blogItemsToMetadata = {};
|
|
164
112
|
const sidebarBlogPosts = options.blogSidebarCount === 'ALL'
|
|
165
113
|
? blogPosts
|
|
166
|
-
:
|
|
114
|
+
: blogPosts.slice(0, options.blogSidebarCount);
|
|
115
|
+
if (archiveBasePath && blogPosts.length) {
|
|
116
|
+
const archiveUrl = (0, utils_1.normalizeUrl)([
|
|
117
|
+
baseUrl,
|
|
118
|
+
routeBasePath,
|
|
119
|
+
archiveBasePath,
|
|
120
|
+
]);
|
|
121
|
+
// Create a blog archive route
|
|
122
|
+
const archiveProp = await createData(`${(0, utils_1.docuHash)(archiveUrl)}.json`, JSON.stringify({ blogPosts }, null, 2));
|
|
123
|
+
addRoute({
|
|
124
|
+
path: archiveUrl,
|
|
125
|
+
component: blogArchiveComponent,
|
|
126
|
+
exact: true,
|
|
127
|
+
modules: {
|
|
128
|
+
archive: aliasedSource(archiveProp),
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
}
|
|
167
132
|
// This prop is useful to provide the blog list sidebar
|
|
168
133
|
const sidebarProp = await createData(
|
|
169
134
|
// Note that this created data path must be in sync with
|
|
170
135
|
// metadataPath provided to mdx-loader.
|
|
171
136
|
`blog-post-list-prop-${pluginId}.json`, JSON.stringify({
|
|
172
|
-
title:
|
|
137
|
+
title: blogSidebarTitle,
|
|
173
138
|
items: sidebarBlogPosts.map((blogPost) => ({
|
|
174
139
|
title: blogPost.metadata.title,
|
|
175
140
|
permalink: blogPost.metadata.permalink,
|
|
@@ -181,7 +146,7 @@ function pluginContentBlog(context, options) {
|
|
|
181
146
|
await createData(
|
|
182
147
|
// Note that this created data path must be in sync with
|
|
183
148
|
// metadataPath provided to mdx-loader.
|
|
184
|
-
`${utils_1.docuHash(metadata.source)}.json`, JSON.stringify(metadata, null, 2));
|
|
149
|
+
`${(0, utils_1.docuHash)(metadata.source)}.json`, JSON.stringify(metadata, null, 2));
|
|
185
150
|
addRoute({
|
|
186
151
|
path: metadata.permalink,
|
|
187
152
|
component: blogPostComponent,
|
|
@@ -197,79 +162,87 @@ function pluginContentBlog(context, options) {
|
|
|
197
162
|
await Promise.all(blogListPaginated.map(async (listPage) => {
|
|
198
163
|
const { metadata, items } = listPage;
|
|
199
164
|
const { permalink } = metadata;
|
|
200
|
-
const pageMetadataPath = await createData(`${utils_1.docuHash(permalink)}.json`, JSON.stringify(metadata, null, 2));
|
|
165
|
+
const pageMetadataPath = await createData(`${(0, utils_1.docuHash)(permalink)}.json`, JSON.stringify(metadata, null, 2));
|
|
201
166
|
addRoute({
|
|
202
167
|
path: permalink,
|
|
203
168
|
component: blogListComponent,
|
|
204
169
|
exact: true,
|
|
205
170
|
modules: {
|
|
206
171
|
sidebar: aliasedSource(sidebarProp),
|
|
207
|
-
items: items.map((postID) => {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
query: {
|
|
214
|
-
truncated: true,
|
|
215
|
-
},
|
|
172
|
+
items: items.map((postID) => ({
|
|
173
|
+
content: {
|
|
174
|
+
__import: true,
|
|
175
|
+
path: blogItemsToMetadata[postID].source,
|
|
176
|
+
query: {
|
|
177
|
+
truncated: true,
|
|
216
178
|
},
|
|
217
|
-
}
|
|
218
|
-
}),
|
|
179
|
+
},
|
|
180
|
+
})),
|
|
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: items.map((postID) => {
|
|
224
|
+
const blogPostMetadata = blogItemsToMetadata[postID];
|
|
225
|
+
return {
|
|
226
|
+
content: {
|
|
227
|
+
__import: true,
|
|
228
|
+
path: blogPostMetadata.source,
|
|
229
|
+
query: {
|
|
230
|
+
truncated: true,
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
}),
|
|
235
|
+
tag: aliasedSource(tagPropPath),
|
|
236
|
+
listMetadata: aliasedSource(listMetadataPath),
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
}));
|
|
240
|
+
}
|
|
241
|
+
await createTagsListPage();
|
|
242
|
+
await Promise.all(Object.values(blogTags).map(createTagPostsListPage));
|
|
243
|
+
},
|
|
244
|
+
translateContent({ content, translationFiles }) {
|
|
245
|
+
return (0, translations_1.translateContent)(content, translationFiles);
|
|
273
246
|
},
|
|
274
247
|
configureWebpack(_config, isServer, { getJSLoader }, content) {
|
|
275
248
|
const { rehypePlugins, remarkPlugins, truncateMarker, beforeDefaultRemarkPlugins, beforeDefaultRehypePlugins, } = options;
|
|
@@ -277,14 +250,15 @@ function pluginContentBlog(context, options) {
|
|
|
277
250
|
siteDir,
|
|
278
251
|
contentPaths,
|
|
279
252
|
truncateMarker,
|
|
280
|
-
sourceToPermalink: blogUtils_1.getSourceToPermalink(content.blogPosts),
|
|
253
|
+
sourceToPermalink: (0, blogUtils_1.getSourceToPermalink)(content.blogPosts),
|
|
281
254
|
onBrokenMarkdownLink: (brokenMarkdownLink) => {
|
|
282
255
|
if (onBrokenMarkdownLinks === 'ignore') {
|
|
283
256
|
return;
|
|
284
257
|
}
|
|
285
|
-
utils_1.reportMessage(`Blog markdown link couldn't be resolved: (${brokenMarkdownLink.link}) in ${brokenMarkdownLink.filePath}`, onBrokenMarkdownLinks);
|
|
258
|
+
(0, utils_1.reportMessage)(`Blog markdown link couldn't be resolved: (${brokenMarkdownLink.link}) in ${brokenMarkdownLink.filePath}`, onBrokenMarkdownLinks);
|
|
286
259
|
},
|
|
287
260
|
};
|
|
261
|
+
const contentDirs = (0, utils_1.getContentPathList)(contentPaths);
|
|
288
262
|
return {
|
|
289
263
|
resolve: {
|
|
290
264
|
alias: {
|
|
@@ -294,8 +268,8 @@ function pluginContentBlog(context, options) {
|
|
|
294
268
|
module: {
|
|
295
269
|
rules: [
|
|
296
270
|
{
|
|
297
|
-
test:
|
|
298
|
-
include:
|
|
271
|
+
test: /\.mdx?$/i,
|
|
272
|
+
include: contentDirs
|
|
299
273
|
// Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
|
|
300
274
|
.map(utils_1.addTrailingPathSeparator),
|
|
301
275
|
use: [
|
|
@@ -305,18 +279,29 @@ function pluginContentBlog(context, options) {
|
|
|
305
279
|
options: {
|
|
306
280
|
remarkPlugins,
|
|
307
281
|
rehypePlugins,
|
|
308
|
-
beforeDefaultRemarkPlugins
|
|
282
|
+
beforeDefaultRemarkPlugins: [
|
|
283
|
+
footnoteIDFixer_1.default,
|
|
284
|
+
...beforeDefaultRemarkPlugins,
|
|
285
|
+
],
|
|
309
286
|
beforeDefaultRehypePlugins,
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
287
|
+
staticDirs: siteConfig.staticDirectories.map((dir) => path_1.default.resolve(siteDir, dir)),
|
|
288
|
+
siteDir,
|
|
289
|
+
isMDXPartial: (0, utils_1.createAbsoluteFilePathMatcher)(options.exclude, contentDirs),
|
|
313
290
|
metadataPath: (mdxPath) => {
|
|
314
|
-
|
|
315
|
-
|
|
291
|
+
// Note that metadataPath must be the same/in-sync as
|
|
292
|
+
// the path from createData for each MDX.
|
|
293
|
+
const aliasedPath = (0, utils_1.aliasedSitePath)(mdxPath, siteDir);
|
|
294
|
+
return path_1.default.join(dataDir, `${(0, utils_1.docuHash)(aliasedPath)}.json`);
|
|
316
295
|
},
|
|
317
296
|
// For blog posts a title in markdown is always removed
|
|
318
297
|
// Blog posts title are rendered separately
|
|
319
298
|
removeContentTitle: true,
|
|
299
|
+
// Assets allow to convert some relative images paths to
|
|
300
|
+
// require() calls
|
|
301
|
+
createAssets: ({ frontMatter, metadata, }) => ({
|
|
302
|
+
image: frontMatter.image,
|
|
303
|
+
authorsImageUrls: metadata.authors.map((author) => author.imageURL),
|
|
304
|
+
}),
|
|
320
305
|
},
|
|
321
306
|
},
|
|
322
307
|
{
|
|
@@ -329,62 +314,54 @@ function pluginContentBlog(context, options) {
|
|
|
329
314
|
},
|
|
330
315
|
};
|
|
331
316
|
},
|
|
332
|
-
async postBuild({ outDir }) {
|
|
333
|
-
|
|
334
|
-
if (!((_a = options.feedOptions) === null || _a === void 0 ? void 0 : _a.type)) {
|
|
317
|
+
async postBuild({ outDir, content }) {
|
|
318
|
+
if (!options.feedOptions.type) {
|
|
335
319
|
return;
|
|
336
320
|
}
|
|
337
|
-
const
|
|
338
|
-
if (!
|
|
321
|
+
const { blogPosts } = content;
|
|
322
|
+
if (!blogPosts.length) {
|
|
339
323
|
return;
|
|
340
324
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
catch (err) {
|
|
349
|
-
throw new Error(`Generating ${feedType} feed failed: ${err}.`);
|
|
350
|
-
}
|
|
351
|
-
}));
|
|
325
|
+
await (0, feed_1.createBlogFeedFiles)({
|
|
326
|
+
blogPosts,
|
|
327
|
+
options,
|
|
328
|
+
outDir,
|
|
329
|
+
siteConfig,
|
|
330
|
+
locale: currentLocale,
|
|
331
|
+
});
|
|
352
332
|
},
|
|
353
333
|
injectHtmlTags({ content }) {
|
|
354
|
-
|
|
355
|
-
if (!content.blogPosts.length) {
|
|
356
|
-
return {};
|
|
357
|
-
}
|
|
358
|
-
if (!((_a = options.feedOptions) === null || _a === void 0 ? void 0 : _a.type)) {
|
|
334
|
+
if (!content.blogPosts.length || !options.feedOptions.type) {
|
|
359
335
|
return {};
|
|
360
336
|
}
|
|
361
337
|
const feedTypes = options.feedOptions.type;
|
|
362
|
-
const
|
|
338
|
+
const feedTitle = options.feedOptions.title ?? context.siteConfig.title;
|
|
363
339
|
const feedsConfig = {
|
|
364
340
|
rss: {
|
|
365
341
|
type: 'application/rss+xml',
|
|
366
342
|
path: 'rss.xml',
|
|
367
|
-
title: `${
|
|
343
|
+
title: `${feedTitle} RSS Feed`,
|
|
368
344
|
},
|
|
369
345
|
atom: {
|
|
370
346
|
type: 'application/atom+xml',
|
|
371
347
|
path: 'atom.xml',
|
|
372
|
-
title: `${
|
|
348
|
+
title: `${feedTitle} Atom Feed`,
|
|
349
|
+
},
|
|
350
|
+
json: {
|
|
351
|
+
type: 'application/json',
|
|
352
|
+
path: 'feed.json',
|
|
353
|
+
title: `${feedTitle} JSON Feed`,
|
|
373
354
|
},
|
|
374
355
|
};
|
|
375
356
|
const headTags = [];
|
|
376
357
|
feedTypes.forEach((feedType) => {
|
|
377
|
-
const
|
|
378
|
-
if (!feedsConfig) {
|
|
379
|
-
return;
|
|
380
|
-
}
|
|
381
|
-
const { type, path: feedConfigPath, title: feedConfigTitle } = feedConfig;
|
|
358
|
+
const { type, path: feedConfigPath, title: feedConfigTitle, } = feedsConfig[feedType];
|
|
382
359
|
headTags.push({
|
|
383
360
|
tagName: 'link',
|
|
384
361
|
attributes: {
|
|
385
362
|
rel: 'alternate',
|
|
386
363
|
type,
|
|
387
|
-
href: utils_1.normalizeUrl([
|
|
364
|
+
href: (0, utils_1.normalizeUrl)([
|
|
388
365
|
baseUrl,
|
|
389
366
|
options.routeBasePath,
|
|
390
367
|
feedConfigPath,
|
|
@@ -400,8 +377,5 @@ function pluginContentBlog(context, options) {
|
|
|
400
377
|
};
|
|
401
378
|
}
|
|
402
379
|
exports.default = pluginContentBlog;
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
return validatedOptions;
|
|
406
|
-
}
|
|
407
|
-
exports.validateOptions = validateOptions;
|
|
380
|
+
var options_1 = require("./options");
|
|
381
|
+
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;
|