@docusaurus/plugin-content-blog 2.0.0-beta.fc64c12e4 → 2.0.0
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 +163 -194
- 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} +41 -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 -110
- package/package.json +23 -19
- package/src/authors.ts +168 -0
- package/src/blogUtils.ts +305 -205
- package/src/feed.ts +171 -0
- package/src/frontMatter.ts +81 -0
- package/src/index.ts +223 -258
- package/src/markdownLoader.ts +11 -16
- package/src/{pluginOptionSchema.ts → options.ts} +54 -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 -129
- package/index.d.ts +0 -138
- package/lib/.tsbuildinfo +0 -1
- package/lib/blogFrontMatter.d.ts +0 -28
- package/lib/pluginOptionSchema.d.ts +0 -34
- package/src/__tests__/__fixtures__/website/blog/2018-12-14-Happy-First-Birthday-Slash.md +0 -5
- package/src/__tests__/__fixtures__/website/blog/_partials/somePartial.md +0 -3
- package/src/__tests__/__fixtures__/website/blog/_partials/subfolder/somePartial.md +0 -3
- package/src/__tests__/__fixtures__/website/blog/_somePartial.md +0 -3
- 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 -116
- 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 -102
- 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,53 +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);
|
|
43
|
+
},
|
|
44
|
+
getTranslationFiles() {
|
|
45
|
+
return (0, translations_1.getTranslationFiles)(options);
|
|
47
46
|
},
|
|
48
47
|
// Fetches blog contents and returns metadata for the necessary routes.
|
|
49
48
|
async loadContent() {
|
|
50
|
-
const { postsPerPage, routeBasePath } = options;
|
|
51
|
-
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);
|
|
52
53
|
if (!blogPosts.length) {
|
|
53
54
|
return {
|
|
55
|
+
blogSidebarTitle,
|
|
54
56
|
blogPosts: [],
|
|
55
57
|
blogListPaginated: [],
|
|
56
58
|
blogTags: {},
|
|
57
|
-
blogTagsListPath
|
|
59
|
+
blogTagsListPath,
|
|
60
|
+
blogTagsPaginated: [],
|
|
58
61
|
};
|
|
59
62
|
}
|
|
60
63
|
// Colocate next and prev metadata.
|
|
@@ -74,72 +77,21 @@ function pluginContentBlog(context, options) {
|
|
|
74
77
|
};
|
|
75
78
|
}
|
|
76
79
|
});
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
for (let page = 0; page < numberOfPages; page += 1) {
|
|
90
|
-
blogListPaginated.push({
|
|
91
|
-
metadata: {
|
|
92
|
-
permalink: blogPaginationPermalink(page),
|
|
93
|
-
page: page + 1,
|
|
94
|
-
postsPerPage,
|
|
95
|
-
totalPages: numberOfPages,
|
|
96
|
-
totalCount,
|
|
97
|
-
previousPage: page !== 0 ? blogPaginationPermalink(page - 1) : null,
|
|
98
|
-
nextPage: page < numberOfPages - 1
|
|
99
|
-
? blogPaginationPermalink(page + 1)
|
|
100
|
-
: null,
|
|
101
|
-
blogDescription: options.blogDescription,
|
|
102
|
-
blogTitle: options.blogTitle,
|
|
103
|
-
},
|
|
104
|
-
items: blogPosts
|
|
105
|
-
.slice(page * postsPerPage, (page + 1) * postsPerPage)
|
|
106
|
-
.map((item) => item.id),
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
const blogTags = {};
|
|
110
|
-
const tagsPath = utils_1.normalizeUrl([basePageUrl, 'tags']);
|
|
111
|
-
blogPosts.forEach((blogPost) => {
|
|
112
|
-
const { tags } = blogPost.metadata;
|
|
113
|
-
if (!tags || tags.length === 0) {
|
|
114
|
-
// TODO: Extract tags out into a separate plugin.
|
|
115
|
-
// eslint-disable-next-line no-param-reassign
|
|
116
|
-
blogPost.metadata.tags = [];
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
// eslint-disable-next-line no-param-reassign
|
|
120
|
-
blogPost.metadata.tags = tags.map((tag) => {
|
|
121
|
-
if (typeof tag === 'string') {
|
|
122
|
-
const normalizedTag = lodash_1.kebabCase(tag);
|
|
123
|
-
const permalink = utils_1.normalizeUrl([tagsPath, normalizedTag]);
|
|
124
|
-
if (!blogTags[normalizedTag]) {
|
|
125
|
-
blogTags[normalizedTag] = {
|
|
126
|
-
// Will only use the name of the first occurrence of the tag.
|
|
127
|
-
name: tag.toLowerCase(),
|
|
128
|
-
items: [],
|
|
129
|
-
permalink,
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
blogTags[normalizedTag].items.push(blogPost.id);
|
|
133
|
-
return {
|
|
134
|
-
label: tag,
|
|
135
|
-
permalink,
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
return tag;
|
|
139
|
-
});
|
|
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,
|
|
140
92
|
});
|
|
141
|
-
const blogTagsListPath = Object.keys(blogTags).length > 0 ? tagsPath : null;
|
|
142
93
|
return {
|
|
94
|
+
blogSidebarTitle,
|
|
143
95
|
blogPosts,
|
|
144
96
|
blogListPaginated,
|
|
145
97
|
blogTags,
|
|
@@ -147,22 +99,50 @@ function pluginContentBlog(context, options) {
|
|
|
147
99
|
};
|
|
148
100
|
},
|
|
149
101
|
async contentLoaded({ content: blogContents, actions }) {
|
|
150
|
-
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
const { blogListComponent, blogPostComponent, blogTagsListComponent, blogTagsPostsComponent, } = options;
|
|
102
|
+
const { blogListComponent, blogPostComponent, blogTagsListComponent, blogTagsPostsComponent, blogArchiveComponent, routeBasePath, archiveBasePath, } = options;
|
|
154
103
|
const { addRoute, createData } = actions;
|
|
155
|
-
const { blogPosts, blogListPaginated, blogTags, blogTagsListPath, } = blogContents;
|
|
104
|
+
const { blogSidebarTitle, blogPosts, blogListPaginated, blogTags, blogTagsListPath, } = blogContents;
|
|
156
105
|
const blogItemsToMetadata = {};
|
|
157
106
|
const sidebarBlogPosts = options.blogSidebarCount === 'ALL'
|
|
158
107
|
? blogPosts
|
|
159
|
-
:
|
|
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
|
+
}
|
|
160
140
|
// This prop is useful to provide the blog list sidebar
|
|
161
141
|
const sidebarProp = await createData(
|
|
162
142
|
// Note that this created data path must be in sync with
|
|
163
143
|
// metadataPath provided to mdx-loader.
|
|
164
144
|
`blog-post-list-prop-${pluginId}.json`, JSON.stringify({
|
|
165
|
-
title:
|
|
145
|
+
title: blogSidebarTitle,
|
|
166
146
|
items: sidebarBlogPosts.map((blogPost) => ({
|
|
167
147
|
title: blogPost.metadata.title,
|
|
168
148
|
permalink: blogPost.metadata.permalink,
|
|
@@ -174,7 +154,7 @@ function pluginContentBlog(context, options) {
|
|
|
174
154
|
await createData(
|
|
175
155
|
// Note that this created data path must be in sync with
|
|
176
156
|
// metadataPath provided to mdx-loader.
|
|
177
|
-
`${utils_1.docuHash(metadata.source)}.json`, JSON.stringify(metadata, null, 2));
|
|
157
|
+
`${(0, utils_1.docuHash)(metadata.source)}.json`, JSON.stringify(metadata, null, 2));
|
|
178
158
|
addRoute({
|
|
179
159
|
path: metadata.permalink,
|
|
180
160
|
component: blogPostComponent,
|
|
@@ -190,95 +170,84 @@ function pluginContentBlog(context, options) {
|
|
|
190
170
|
await Promise.all(blogListPaginated.map(async (listPage) => {
|
|
191
171
|
const { metadata, items } = listPage;
|
|
192
172
|
const { permalink } = metadata;
|
|
193
|
-
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));
|
|
194
174
|
addRoute({
|
|
195
175
|
path: permalink,
|
|
196
176
|
component: blogListComponent,
|
|
197
177
|
exact: true,
|
|
198
178
|
modules: {
|
|
199
179
|
sidebar: aliasedSource(sidebarProp),
|
|
200
|
-
items: items
|
|
201
|
-
// To tell routes.js this is an import and not a nested object to recurse.
|
|
202
|
-
return {
|
|
203
|
-
content: {
|
|
204
|
-
__import: true,
|
|
205
|
-
path: blogItemsToMetadata[postID].source,
|
|
206
|
-
query: {
|
|
207
|
-
truncated: true,
|
|
208
|
-
},
|
|
209
|
-
},
|
|
210
|
-
};
|
|
211
|
-
}),
|
|
180
|
+
items: blogPostItemsModule(items),
|
|
212
181
|
metadata: aliasedSource(pageMetadataPath),
|
|
213
182
|
},
|
|
214
183
|
});
|
|
215
184
|
}));
|
|
216
|
-
// Tags.
|
|
217
|
-
if (
|
|
185
|
+
// Tags. This is the last part so we early-return if there are no tags.
|
|
186
|
+
if (Object.keys(blogTags).length === 0) {
|
|
218
187
|
return;
|
|
219
188
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
count: items.length,
|
|
228
|
-
permalink,
|
|
229
|
-
};
|
|
230
|
-
const tagsMetadataPath = await createData(`${utils_1.docuHash(permalink)}.json`, JSON.stringify(tagsModule[tag], null, 2));
|
|
231
|
-
addRoute({
|
|
232
|
-
path: permalink,
|
|
233
|
-
component: blogTagsPostsComponent,
|
|
234
|
-
exact: true,
|
|
235
|
-
modules: {
|
|
236
|
-
sidebar: aliasedSource(sidebarProp),
|
|
237
|
-
items: items.map((postID) => {
|
|
238
|
-
const metadata = blogItemsToMetadata[postID];
|
|
239
|
-
return {
|
|
240
|
-
content: {
|
|
241
|
-
__import: true,
|
|
242
|
-
path: metadata.source,
|
|
243
|
-
query: {
|
|
244
|
-
truncated: true,
|
|
245
|
-
},
|
|
246
|
-
},
|
|
247
|
-
};
|
|
248
|
-
}),
|
|
249
|
-
metadata: aliasedSource(tagsMetadataPath),
|
|
250
|
-
},
|
|
251
|
-
});
|
|
252
|
-
}));
|
|
253
|
-
// Only create /tags page if there are tags.
|
|
254
|
-
if (Object.keys(blogTags).length > 0) {
|
|
255
|
-
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));
|
|
256
196
|
addRoute({
|
|
257
197
|
path: blogTagsListPath,
|
|
258
198
|
component: blogTagsListComponent,
|
|
259
199
|
exact: true,
|
|
260
200
|
modules: {
|
|
261
201
|
sidebar: aliasedSource(sidebarProp),
|
|
262
|
-
tags: aliasedSource(
|
|
202
|
+
tags: aliasedSource(tagsPropPath),
|
|
263
203
|
},
|
|
264
204
|
});
|
|
265
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);
|
|
266
235
|
},
|
|
267
236
|
configureWebpack(_config, isServer, { getJSLoader }, content) {
|
|
268
|
-
const { rehypePlugins, remarkPlugins, truncateMarker, beforeDefaultRemarkPlugins, beforeDefaultRehypePlugins, } = options;
|
|
237
|
+
const { admonitions, rehypePlugins, remarkPlugins, truncateMarker, beforeDefaultRemarkPlugins, beforeDefaultRehypePlugins, } = options;
|
|
269
238
|
const markdownLoaderOptions = {
|
|
270
239
|
siteDir,
|
|
271
240
|
contentPaths,
|
|
272
241
|
truncateMarker,
|
|
273
|
-
sourceToPermalink: blogUtils_1.getSourceToPermalink(content.blogPosts),
|
|
242
|
+
sourceToPermalink: (0, blogUtils_1.getSourceToPermalink)(content.blogPosts),
|
|
274
243
|
onBrokenMarkdownLink: (brokenMarkdownLink) => {
|
|
275
244
|
if (onBrokenMarkdownLinks === 'ignore') {
|
|
276
245
|
return;
|
|
277
246
|
}
|
|
278
|
-
|
|
247
|
+
logger_1.default.report(onBrokenMarkdownLinks) `Blog markdown link couldn't be resolved: (url=${brokenMarkdownLink.link}) in path=${brokenMarkdownLink.filePath}`;
|
|
279
248
|
},
|
|
280
249
|
};
|
|
281
|
-
const contentDirs =
|
|
250
|
+
const contentDirs = (0, utils_1.getContentPathList)(contentPaths);
|
|
282
251
|
return {
|
|
283
252
|
resolve: {
|
|
284
253
|
alias: {
|
|
@@ -288,7 +257,7 @@ function pluginContentBlog(context, options) {
|
|
|
288
257
|
module: {
|
|
289
258
|
rules: [
|
|
290
259
|
{
|
|
291
|
-
test:
|
|
260
|
+
test: /\.mdx?$/i,
|
|
292
261
|
include: contentDirs
|
|
293
262
|
// Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
|
|
294
263
|
.map(utils_1.addTrailingPathSeparator),
|
|
@@ -297,21 +266,32 @@ function pluginContentBlog(context, options) {
|
|
|
297
266
|
{
|
|
298
267
|
loader: require.resolve('@docusaurus/mdx-loader'),
|
|
299
268
|
options: {
|
|
269
|
+
admonitions,
|
|
300
270
|
remarkPlugins,
|
|
301
271
|
rehypePlugins,
|
|
302
|
-
beforeDefaultRemarkPlugins
|
|
272
|
+
beforeDefaultRemarkPlugins: [
|
|
273
|
+
footnoteIDFixer_1.default,
|
|
274
|
+
...beforeDefaultRemarkPlugins,
|
|
275
|
+
],
|
|
303
276
|
beforeDefaultRehypePlugins,
|
|
304
|
-
|
|
305
|
-
|
|
277
|
+
staticDirs: siteConfig.staticDirectories.map((dir) => path_1.default.resolve(siteDir, dir)),
|
|
278
|
+
siteDir,
|
|
279
|
+
isMDXPartial: (0, utils_1.createAbsoluteFilePathMatcher)(options.exclude, contentDirs),
|
|
306
280
|
metadataPath: (mdxPath) => {
|
|
307
281
|
// Note that metadataPath must be the same/in-sync as
|
|
308
282
|
// the path from createData for each MDX.
|
|
309
|
-
const aliasedPath = utils_1.aliasedSitePath(mdxPath, siteDir);
|
|
310
|
-
return path_1.default.join(dataDir, `${utils_1.docuHash(aliasedPath)}.json`);
|
|
283
|
+
const aliasedPath = (0, utils_1.aliasedSitePath)(mdxPath, siteDir);
|
|
284
|
+
return path_1.default.join(dataDir, `${(0, utils_1.docuHash)(aliasedPath)}.json`);
|
|
311
285
|
},
|
|
312
286
|
// For blog posts a title in markdown is always removed
|
|
313
287
|
// Blog posts title are rendered separately
|
|
314
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
|
+
}),
|
|
315
295
|
},
|
|
316
296
|
},
|
|
317
297
|
{
|
|
@@ -324,62 +304,54 @@ function pluginContentBlog(context, options) {
|
|
|
324
304
|
},
|
|
325
305
|
};
|
|
326
306
|
},
|
|
327
|
-
async postBuild({ outDir }) {
|
|
328
|
-
|
|
329
|
-
if (!((_a = options.feedOptions) === null || _a === void 0 ? void 0 : _a.type)) {
|
|
307
|
+
async postBuild({ outDir, content }) {
|
|
308
|
+
if (!options.feedOptions.type) {
|
|
330
309
|
return;
|
|
331
310
|
}
|
|
332
|
-
const
|
|
333
|
-
if (!
|
|
311
|
+
const { blogPosts } = content;
|
|
312
|
+
if (!blogPosts.length) {
|
|
334
313
|
return;
|
|
335
314
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
catch (err) {
|
|
344
|
-
throw new Error(`Generating ${feedType} feed failed: ${err}.`);
|
|
345
|
-
}
|
|
346
|
-
}));
|
|
315
|
+
await (0, feed_1.createBlogFeedFiles)({
|
|
316
|
+
blogPosts,
|
|
317
|
+
options,
|
|
318
|
+
outDir,
|
|
319
|
+
siteConfig,
|
|
320
|
+
locale: currentLocale,
|
|
321
|
+
});
|
|
347
322
|
},
|
|
348
323
|
injectHtmlTags({ content }) {
|
|
349
|
-
|
|
350
|
-
if (!content.blogPosts.length) {
|
|
351
|
-
return {};
|
|
352
|
-
}
|
|
353
|
-
if (!((_a = options.feedOptions) === null || _a === void 0 ? void 0 : _a.type)) {
|
|
324
|
+
if (!content.blogPosts.length || !options.feedOptions.type) {
|
|
354
325
|
return {};
|
|
355
326
|
}
|
|
356
327
|
const feedTypes = options.feedOptions.type;
|
|
357
|
-
const
|
|
328
|
+
const feedTitle = options.feedOptions.title ?? context.siteConfig.title;
|
|
358
329
|
const feedsConfig = {
|
|
359
330
|
rss: {
|
|
360
331
|
type: 'application/rss+xml',
|
|
361
332
|
path: 'rss.xml',
|
|
362
|
-
title: `${
|
|
333
|
+
title: `${feedTitle} RSS Feed`,
|
|
363
334
|
},
|
|
364
335
|
atom: {
|
|
365
336
|
type: 'application/atom+xml',
|
|
366
337
|
path: 'atom.xml',
|
|
367
|
-
title: `${
|
|
338
|
+
title: `${feedTitle} Atom Feed`,
|
|
339
|
+
},
|
|
340
|
+
json: {
|
|
341
|
+
type: 'application/json',
|
|
342
|
+
path: 'feed.json',
|
|
343
|
+
title: `${feedTitle} JSON Feed`,
|
|
368
344
|
},
|
|
369
345
|
};
|
|
370
346
|
const headTags = [];
|
|
371
347
|
feedTypes.forEach((feedType) => {
|
|
372
|
-
const
|
|
373
|
-
if (!feedsConfig) {
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
|
-
const { type, path: feedConfigPath, title: feedConfigTitle } = feedConfig;
|
|
348
|
+
const { type, path: feedConfigPath, title: feedConfigTitle, } = feedsConfig[feedType];
|
|
377
349
|
headTags.push({
|
|
378
350
|
tagName: 'link',
|
|
379
351
|
attributes: {
|
|
380
352
|
rel: 'alternate',
|
|
381
353
|
type,
|
|
382
|
-
href: utils_1.normalizeUrl([
|
|
354
|
+
href: (0, utils_1.normalizeUrl)([
|
|
383
355
|
baseUrl,
|
|
384
356
|
options.routeBasePath,
|
|
385
357
|
feedConfigPath,
|
|
@@ -395,8 +367,5 @@ function pluginContentBlog(context, options) {
|
|
|
395
367
|
};
|
|
396
368
|
}
|
|
397
369
|
exports.default = pluginContentBlog;
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
return validatedOptions;
|
|
401
|
-
}
|
|
402
|
-
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;
|