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