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