@docusaurus/plugin-content-blog 3.3.2 → 3.4.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.
@@ -7,11 +7,8 @@
7
7
  /// <reference path="../src/plugin-content-blog.d.ts" />
8
8
  import type { LoadContext } from '@docusaurus/types';
9
9
  import type { PluginOptions, BlogPost, BlogTags, BlogPaginated } from '@docusaurus/plugin-content-blog';
10
- import type { BlogContentPaths, BlogMarkdownLoaderOptions } from './types';
10
+ import type { BlogContentPaths } from './types';
11
11
  export declare function truncate(fileString: string, truncateMarker: RegExp): string;
12
- export declare function getSourceToPermalink(blogPosts: BlogPost[]): {
13
- [aliasedPath: string]: string;
14
- };
15
12
  export declare function paginateBlogPosts({ blogPosts, basePageUrl, blogTitle, blogDescription, postsPerPageOption, pageBasePath, }: {
16
13
  blogPosts: BlogPost[];
17
14
  basePageUrl: string;
@@ -35,11 +32,6 @@ type ParsedBlogFileName = {
35
32
  };
36
33
  export declare function parseBlogFileName(blogSourceRelative: string): ParsedBlogFileName;
37
34
  export declare function generateBlogPosts(contentPaths: BlogContentPaths, context: LoadContext, options: PluginOptions): Promise<BlogPost[]>;
38
- export type LinkifyParams = {
39
- filePath: string;
40
- fileString: string;
41
- } & Pick<BlogMarkdownLoaderOptions, 'sourceToPermalink' | 'siteDir' | 'contentPaths' | 'onBrokenMarkdownLink'>;
42
- export declare function linkify({ filePath, contentPaths, fileString, siteDir, sourceToPermalink, onBrokenMarkdownLink, }: LinkifyParams): string;
43
35
  export declare function applyProcessBlogPosts({ blogPosts, processBlogPosts, }: {
44
36
  blogPosts: BlogPost[];
45
37
  processBlogPosts: PluginOptions['processBlogPosts'];
package/lib/blogUtils.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.applyProcessBlogPosts = exports.linkify = exports.generateBlogPosts = exports.parseBlogFileName = exports.getBlogTags = exports.shouldBeListed = exports.paginateBlogPosts = exports.getSourceToPermalink = exports.truncate = void 0;
9
+ exports.applyProcessBlogPosts = exports.generateBlogPosts = exports.parseBlogFileName = exports.getBlogTags = exports.shouldBeListed = exports.paginateBlogPosts = exports.truncate = void 0;
10
10
  const tslib_1 = require("tslib");
11
11
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
12
  const path_1 = tslib_1.__importDefault(require("path"));
@@ -14,16 +14,13 @@ const lodash_1 = tslib_1.__importDefault(require("lodash"));
14
14
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
15
15
  const reading_time_1 = tslib_1.__importDefault(require("reading-time"));
16
16
  const utils_1 = require("@docusaurus/utils");
17
+ const utils_validation_1 = require("@docusaurus/utils-validation");
17
18
  const frontMatter_1 = require("./frontMatter");
18
19
  const authors_1 = require("./authors");
19
20
  function truncate(fileString, truncateMarker) {
20
21
  return fileString.split(truncateMarker, 1).shift();
21
22
  }
22
23
  exports.truncate = truncate;
23
- function getSourceToPermalink(blogPosts) {
24
- return Object.fromEntries(blogPosts.map(({ metadata: { source, permalink } }) => [source, permalink]));
25
- }
26
- exports.getSourceToPermalink = getSourceToPermalink;
27
24
  function paginateBlogPosts({ blogPosts, basePageUrl, blogTitle, blogDescription, postsPerPageOption, pageBasePath, }) {
28
25
  const totalCount = blogPosts.length;
29
26
  const postsPerPage = postsPerPageOption === 'ALL' ? totalCount : postsPerPageOption;
@@ -67,9 +64,11 @@ function getBlogTags({ blogPosts, ...params }) {
67
64
  isUnlisted: (item) => item.metadata.unlisted,
68
65
  });
69
66
  return {
67
+ inline: tag.inline,
70
68
  label: tag.label,
71
- items: tagVisibility.listedItems.map((item) => item.id),
72
69
  permalink: tag.permalink,
70
+ description: tag.description,
71
+ items: tagVisibility.listedItems.map((item) => item.id),
73
72
  pages: paginateBlogPosts({
74
73
  blogPosts: tagVisibility.listedItems,
75
74
  basePageUrl: tag.permalink,
@@ -116,7 +115,7 @@ async function parseBlogPostMarkdownFile({ filePath, parseFrontMatter, }) {
116
115
  }
117
116
  }
118
117
  const defaultReadingTime = ({ content, options }) => (0, reading_time_1.default)(content, options).minutes;
119
- async function processBlogSourceFile(blogSourceRelative, contentPaths, context, options, authorsMap) {
118
+ async function processBlogSourceFile(blogSourceRelative, contentPaths, context, options, tagsFile, authorsMap) {
120
119
  const { siteConfig: { baseUrl, markdown: { parseFrontMatter }, }, siteDir, i18n, } = context;
121
120
  const { routeBasePath, tagsBasePath: tagsRouteBasePath, truncateMarker, showReadingTime, editUrl, } = options;
122
121
  // Lookup in localized folder in priority
@@ -190,12 +189,19 @@ async function processBlogSourceFile(blogSourceRelative, contentPaths, context,
190
189
  }
191
190
  return undefined;
192
191
  }
193
- const tagsBasePath = (0, utils_1.normalizeUrl)([
192
+ const tagsBaseRoutePath = (0, utils_1.normalizeUrl)([
194
193
  baseUrl,
195
194
  routeBasePath,
196
195
  tagsRouteBasePath,
197
196
  ]);
198
197
  const authors = (0, authors_1.getBlogPostAuthors)({ authorsMap, frontMatter, baseUrl });
198
+ const tags = (0, utils_1.normalizeTags)({
199
+ options,
200
+ source: blogSourceRelative,
201
+ frontMatterTags: frontMatter.tags,
202
+ tagsBaseRoutePath,
203
+ tagsFile,
204
+ });
199
205
  return {
200
206
  id: slug,
201
207
  metadata: {
@@ -205,7 +211,7 @@ async function processBlogSourceFile(blogSourceRelative, contentPaths, context,
205
211
  title,
206
212
  description,
207
213
  date,
208
- tags: (0, utils_1.normalizeFrontMatterTags)(tagsBasePath, frontMatter.tags),
214
+ tags,
209
215
  readingTime: showReadingTime
210
216
  ? options.readingTime({
211
217
  content,
@@ -236,9 +242,10 @@ async function generateBlogPosts(contentPaths, context, options) {
236
242
  contentPaths,
237
243
  authorsMapPath: options.authorsMapPath,
238
244
  });
245
+ const tagsFile = await (0, utils_validation_1.getTagsFile)({ contentPaths, tags: options.tags });
239
246
  async function doProcessBlogSourceFile(blogSourceFile) {
240
247
  try {
241
- return await processBlogSourceFile(blogSourceFile, contentPaths, context, options, authorsMap);
248
+ return await processBlogSourceFile(blogSourceFile, contentPaths, context, options, tagsFile, authorsMap);
242
249
  }
243
250
  catch (err) {
244
251
  throw new Error(`Processing of blog source file path=${blogSourceFile} failed.`, { cause: err });
@@ -252,18 +259,6 @@ async function generateBlogPosts(contentPaths, context, options) {
252
259
  return blogPosts;
253
260
  }
254
261
  exports.generateBlogPosts = generateBlogPosts;
255
- function linkify({ filePath, contentPaths, fileString, siteDir, sourceToPermalink, onBrokenMarkdownLink, }) {
256
- const { newContent, brokenMarkdownLinks } = (0, utils_1.replaceMarkdownLinks)({
257
- siteDir,
258
- fileString,
259
- filePath,
260
- contentPaths,
261
- sourceToPermalink,
262
- });
263
- brokenMarkdownLinks.forEach((l) => onBrokenMarkdownLink(l));
264
- return newContent;
265
- }
266
- exports.linkify = linkify;
267
262
  async function applyProcessBlogPosts({ blogPosts, processBlogPosts, }) {
268
263
  const processedBlogPosts = await processBlogPosts({ blogPosts });
269
264
  if (Array.isArray(processedBlogPosts)) {
package/lib/feed.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  /// <reference path="../src/plugin-content-blog.d.ts" />
8
- import type { DocusaurusConfig } from '@docusaurus/types';
8
+ import type { DocusaurusConfig, HtmlTags, LoadContext } from '@docusaurus/types';
9
9
  import type { PluginOptions, BlogPost } from '@docusaurus/plugin-content-blog';
10
10
  export declare function createBlogFeedFiles({ blogPosts: allBlogPosts, options, siteConfig, outDir, locale, }: {
11
11
  blogPosts: BlogPost[];
@@ -14,3 +14,7 @@ export declare function createBlogFeedFiles({ blogPosts: allBlogPosts, options,
14
14
  outDir: string;
15
15
  locale: string;
16
16
  }): Promise<void>;
17
+ export declare function createFeedHtmlHeadTags({ context, options, }: {
18
+ context: LoadContext;
19
+ options: PluginOptions;
20
+ }): HtmlTags;
package/lib/feed.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.createBlogFeedFiles = void 0;
9
+ exports.createFeedHtmlHeadTags = exports.createBlogFeedFiles = void 0;
10
10
  const tslib_1 = require("tslib");
11
11
  const path_1 = tslib_1.__importDefault(require("path"));
12
12
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
@@ -151,3 +151,46 @@ async function createBlogFeedFiles({ blogPosts: allBlogPosts, options, siteConfi
151
151
  })));
152
152
  }
153
153
  exports.createBlogFeedFiles = createBlogFeedFiles;
154
+ function createFeedHtmlHeadTags({ context, options, }) {
155
+ const feedTypes = options.feedOptions.type;
156
+ if (!feedTypes) {
157
+ return [];
158
+ }
159
+ const feedTitle = options.feedOptions.title ?? context.siteConfig.title;
160
+ const feedsConfig = {
161
+ rss: {
162
+ type: 'application/rss+xml',
163
+ path: 'rss.xml',
164
+ title: `${feedTitle} RSS Feed`,
165
+ },
166
+ atom: {
167
+ type: 'application/atom+xml',
168
+ path: 'atom.xml',
169
+ title: `${feedTitle} Atom Feed`,
170
+ },
171
+ json: {
172
+ type: 'application/json',
173
+ path: 'feed.json',
174
+ title: `${feedTitle} JSON Feed`,
175
+ },
176
+ };
177
+ const headTags = [];
178
+ feedTypes.forEach((feedType) => {
179
+ const { type, path: feedConfigPath, title: feedConfigTitle, } = feedsConfig[feedType];
180
+ headTags.push({
181
+ tagName: 'link',
182
+ attributes: {
183
+ rel: 'alternate',
184
+ type,
185
+ href: (0, utils_1.normalizeUrl)([
186
+ context.siteConfig.baseUrl,
187
+ options.routeBasePath,
188
+ feedConfigPath,
189
+ ]),
190
+ title: feedConfigTitle,
191
+ },
192
+ });
193
+ });
194
+ return headTags;
195
+ }
196
+ exports.createFeedHtmlHeadTags = createFeedHtmlHeadTags;
package/lib/index.js CHANGED
@@ -11,24 +11,52 @@ const tslib_1 = require("tslib");
11
11
  const path_1 = tslib_1.__importDefault(require("path"));
12
12
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
13
13
  const utils_1 = require("@docusaurus/utils");
14
+ const utils_validation_1 = require("@docusaurus/utils-validation");
14
15
  const blogUtils_1 = require("./blogUtils");
15
16
  const footnoteIDFixer_1 = tslib_1.__importDefault(require("./remark/footnoteIDFixer"));
16
17
  const translations_1 = require("./translations");
17
18
  const feed_1 = require("./feed");
18
19
  const routes_1 = require("./routes");
20
+ const PluginName = 'docusaurus-plugin-content-blog';
21
+ // TODO this is bad, we should have a better way to do this (new lifecycle?)
22
+ // The source to permalink is currently a mutable map passed to the mdx loader
23
+ // for link resolution
24
+ // see https://github.com/facebook/docusaurus/pull/10185
25
+ function createSourceToPermalinkHelper() {
26
+ const sourceToPermalink = new Map();
27
+ function computeSourceToPermalink(content) {
28
+ return new Map(content.blogPosts.map(({ metadata: { source, permalink } }) => [
29
+ source,
30
+ permalink,
31
+ ]));
32
+ }
33
+ // Mutable map update :/
34
+ function update(content) {
35
+ sourceToPermalink.clear();
36
+ computeSourceToPermalink(content).forEach((value, key) => {
37
+ sourceToPermalink.set(key, value);
38
+ });
39
+ }
40
+ return { get: () => sourceToPermalink, update };
41
+ }
19
42
  async function pluginContentBlog(context, options) {
20
43
  const { siteDir, siteConfig, generatedFilesDir, localizationDir, i18n: { currentLocale }, } = context;
44
+ const router = siteConfig.future.experimental_router;
45
+ const isBlogFeedDisabledBecauseOfHashRouter = router === 'hash' && !!options.feedOptions.type;
46
+ if (isBlogFeedDisabledBecauseOfHashRouter) {
47
+ logger_1.default.warn(`${PluginName} feed feature does not support the Hash Router. Feeds won't be generated.`);
48
+ }
21
49
  const { onBrokenMarkdownLinks, baseUrl } = siteConfig;
22
50
  const contentPaths = {
23
51
  contentPath: path_1.default.resolve(siteDir, options.path),
24
52
  contentPathLocalized: (0, utils_1.getPluginI18nPath)({
25
53
  localizationDir,
26
- pluginName: 'docusaurus-plugin-content-blog',
54
+ pluginName: PluginName,
27
55
  pluginId: options.id,
28
56
  }),
29
57
  };
30
58
  const pluginId = options.id ?? utils_1.DEFAULT_PLUGIN_ID;
31
- const pluginDataDirRoot = path_1.default.join(generatedFilesDir, 'docusaurus-plugin-content-blog');
59
+ const pluginDataDirRoot = path_1.default.join(generatedFilesDir, PluginName);
32
60
  const dataDir = path_1.default.join(pluginDataDirRoot, pluginId);
33
61
  // TODO Docusaurus v4 breaking change
34
62
  // module aliasing should be automatic
@@ -38,12 +66,21 @@ async function pluginContentBlog(context, options) {
38
66
  filePath: options.authorsMapPath,
39
67
  contentPaths,
40
68
  });
69
+ const sourceToPermalinkHelper = createSourceToPermalinkHelper();
41
70
  return {
42
- name: 'docusaurus-plugin-content-blog',
71
+ name: PluginName,
43
72
  getPathsToWatch() {
44
73
  const { include } = options;
45
74
  const contentMarkdownGlobs = (0, utils_1.getContentPathList)(contentPaths).flatMap((contentPath) => include.map((pattern) => `${contentPath}/${pattern}`));
46
- return [authorsMapFilePath, ...contentMarkdownGlobs].filter(Boolean);
75
+ const tagsFilePaths = (0, utils_validation_1.getTagsFilePathsToWatch)({
76
+ contentPaths,
77
+ tags: options.tags,
78
+ });
79
+ return [
80
+ authorsMapFilePath,
81
+ ...tagsFilePaths,
82
+ ...contentMarkdownGlobs,
83
+ ].filter(Boolean);
47
84
  },
48
85
  getTranslationFiles() {
49
86
  return (0, translations_1.getTranslationFiles)(options);
@@ -111,6 +148,7 @@ async function pluginContentBlog(context, options) {
111
148
  };
112
149
  },
113
150
  async contentLoaded({ content, actions }) {
151
+ sourceToPermalinkHelper.update(content);
114
152
  await (0, routes_1.createAllRoutes)({
115
153
  baseUrl,
116
154
  content,
@@ -122,21 +160,66 @@ async function pluginContentBlog(context, options) {
122
160
  translateContent({ content, translationFiles }) {
123
161
  return (0, translations_1.translateContent)(content, translationFiles);
124
162
  },
125
- configureWebpack(_config, isServer, utils, content) {
163
+ configureWebpack() {
126
164
  const { admonitions, rehypePlugins, remarkPlugins, truncateMarker, beforeDefaultRemarkPlugins, beforeDefaultRehypePlugins, } = options;
127
- const markdownLoaderOptions = {
128
- siteDir,
129
- contentPaths,
130
- truncateMarker,
131
- sourceToPermalink: (0, blogUtils_1.getSourceToPermalink)(content.blogPosts),
132
- onBrokenMarkdownLink: (brokenMarkdownLink) => {
133
- if (onBrokenMarkdownLinks === 'ignore') {
134
- return;
135
- }
136
- logger_1.default.report(onBrokenMarkdownLinks) `Blog markdown link couldn't be resolved: (url=${brokenMarkdownLink.link}) in path=${brokenMarkdownLink.filePath}`;
137
- },
138
- };
139
165
  const contentDirs = (0, utils_1.getContentPathList)(contentPaths);
166
+ function createMDXLoader() {
167
+ const loaderOptions = {
168
+ admonitions,
169
+ remarkPlugins,
170
+ rehypePlugins,
171
+ beforeDefaultRemarkPlugins: [
172
+ footnoteIDFixer_1.default,
173
+ ...beforeDefaultRemarkPlugins,
174
+ ],
175
+ beforeDefaultRehypePlugins,
176
+ staticDirs: siteConfig.staticDirectories.map((dir) => path_1.default.resolve(siteDir, dir)),
177
+ siteDir,
178
+ isMDXPartial: (0, utils_1.createAbsoluteFilePathMatcher)(options.exclude, contentDirs),
179
+ metadataPath: (mdxPath) => {
180
+ // Note that metadataPath must be the same/in-sync as
181
+ // the path from createData for each MDX.
182
+ const aliasedPath = (0, utils_1.aliasedSitePath)(mdxPath, siteDir);
183
+ return path_1.default.join(dataDir, `${(0, utils_1.docuHash)(aliasedPath)}.json`);
184
+ },
185
+ // For blog posts a title in markdown is always removed
186
+ // Blog posts title are rendered separately
187
+ removeContentTitle: true,
188
+ // Assets allow to convert some relative images paths to
189
+ // require() calls
190
+ // @ts-expect-error: TODO fix typing issue
191
+ createAssets: ({ frontMatter, metadata, }) => ({
192
+ image: frontMatter.image,
193
+ authorsImageUrls: metadata.authors.map((author) => author.imageURL),
194
+ }),
195
+ markdownConfig: siteConfig.markdown,
196
+ resolveMarkdownLink: ({ linkPathname, sourceFilePath }) => {
197
+ const permalink = (0, utils_1.resolveMarkdownLinkPathname)(linkPathname, {
198
+ sourceFilePath,
199
+ sourceToPermalink: sourceToPermalinkHelper.get(),
200
+ siteDir,
201
+ contentPaths,
202
+ });
203
+ if (permalink === null) {
204
+ logger_1.default.report(onBrokenMarkdownLinks) `Blog markdown link couldn't be resolved: (url=${linkPathname}) in source file path=${sourceFilePath}`;
205
+ }
206
+ return permalink;
207
+ },
208
+ };
209
+ return {
210
+ loader: require.resolve('@docusaurus/mdx-loader'),
211
+ options: loaderOptions,
212
+ };
213
+ }
214
+ function createBlogMarkdownLoader() {
215
+ const loaderOptions = {
216
+ truncateMarker,
217
+ };
218
+ return {
219
+ loader: path_1.default.resolve(__dirname, './markdownLoader.js'),
220
+ options: loaderOptions,
221
+ };
222
+ }
140
223
  return {
141
224
  resolve: {
142
225
  alias: {
@@ -150,59 +233,20 @@ async function pluginContentBlog(context, options) {
150
233
  include: contentDirs
151
234
  // Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
152
235
  .map(utils_1.addTrailingPathSeparator),
153
- use: [
154
- {
155
- loader: require.resolve('@docusaurus/mdx-loader'),
156
- options: {
157
- admonitions,
158
- remarkPlugins,
159
- rehypePlugins,
160
- beforeDefaultRemarkPlugins: [
161
- footnoteIDFixer_1.default,
162
- ...beforeDefaultRemarkPlugins,
163
- ],
164
- beforeDefaultRehypePlugins,
165
- staticDirs: siteConfig.staticDirectories.map((dir) => path_1.default.resolve(siteDir, dir)),
166
- siteDir,
167
- isMDXPartial: (0, utils_1.createAbsoluteFilePathMatcher)(options.exclude, contentDirs),
168
- metadataPath: (mdxPath) => {
169
- // Note that metadataPath must be the same/in-sync as
170
- // the path from createData for each MDX.
171
- const aliasedPath = (0, utils_1.aliasedSitePath)(mdxPath, siteDir);
172
- return path_1.default.join(dataDir, `${(0, utils_1.docuHash)(aliasedPath)}.json`);
173
- },
174
- // For blog posts a title in markdown is always removed
175
- // Blog posts title are rendered separately
176
- removeContentTitle: true,
177
- // Assets allow to convert some relative images paths to
178
- // require() calls
179
- createAssets: ({ frontMatter, metadata, }) => ({
180
- image: frontMatter.image,
181
- authorsImageUrls: metadata.authors.map((author) => author.imageURL),
182
- }),
183
- markdownConfig: siteConfig.markdown,
184
- },
185
- },
186
- {
187
- loader: path_1.default.resolve(__dirname, './markdownLoader.js'),
188
- options: markdownLoaderOptions,
189
- },
190
- ].filter(Boolean),
236
+ use: [createMDXLoader(), createBlogMarkdownLoader()],
191
237
  },
192
238
  ],
193
239
  },
194
240
  };
195
241
  },
196
242
  async postBuild({ outDir, content }) {
197
- if (!options.feedOptions.type) {
198
- return;
199
- }
200
- const { blogPosts } = content;
201
- if (!blogPosts.length) {
243
+ if (!content.blogPosts.length ||
244
+ !options.feedOptions.type ||
245
+ isBlogFeedDisabledBecauseOfHashRouter) {
202
246
  return;
203
247
  }
204
248
  await (0, feed_1.createBlogFeedFiles)({
205
- blogPosts,
249
+ blogPosts: content.blogPosts,
206
250
  options,
207
251
  outDir,
208
252
  siteConfig,
@@ -210,48 +254,12 @@ async function pluginContentBlog(context, options) {
210
254
  });
211
255
  },
212
256
  injectHtmlTags({ content }) {
213
- if (!content.blogPosts.length || !options.feedOptions.type) {
257
+ if (!content.blogPosts.length ||
258
+ !options.feedOptions.type ||
259
+ isBlogFeedDisabledBecauseOfHashRouter) {
214
260
  return {};
215
261
  }
216
- const feedTypes = options.feedOptions.type;
217
- const feedTitle = options.feedOptions.title ?? context.siteConfig.title;
218
- const feedsConfig = {
219
- rss: {
220
- type: 'application/rss+xml',
221
- path: 'rss.xml',
222
- title: `${feedTitle} RSS Feed`,
223
- },
224
- atom: {
225
- type: 'application/atom+xml',
226
- path: 'atom.xml',
227
- title: `${feedTitle} Atom Feed`,
228
- },
229
- json: {
230
- type: 'application/json',
231
- path: 'feed.json',
232
- title: `${feedTitle} JSON Feed`,
233
- },
234
- };
235
- const headTags = [];
236
- feedTypes.forEach((feedType) => {
237
- const { type, path: feedConfigPath, title: feedConfigTitle, } = feedsConfig[feedType];
238
- headTags.push({
239
- tagName: 'link',
240
- attributes: {
241
- rel: 'alternate',
242
- type,
243
- href: (0, utils_1.normalizeUrl)([
244
- baseUrl,
245
- options.routeBasePath,
246
- feedConfigPath,
247
- ]),
248
- title: feedConfigTitle,
249
- },
250
- });
251
- });
252
- return {
253
- headTags,
254
- };
262
+ return { headTags: (0, feed_1.createFeedHtmlHeadTags)({ context, options }) };
255
263
  },
256
264
  };
257
265
  }
@@ -8,20 +8,16 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  const blogUtils_1 = require("./blogUtils");
10
10
  function markdownLoader(source) {
11
- const filePath = this.resourcePath;
12
11
  const fileString = source;
13
12
  const callback = this.async();
14
13
  const markdownLoaderOptions = this.getOptions();
15
14
  // Linkify blog posts
16
- let finalContent = (0, blogUtils_1.linkify)({
17
- fileString,
18
- filePath,
19
- ...markdownLoaderOptions,
20
- });
15
+ let finalContent = fileString;
21
16
  // Truncate content if requested (e.g: file.md?truncated=true).
22
17
  const truncated = this.resourceQuery
23
18
  ? !!new URLSearchParams(this.resourceQuery.slice(1)).get('truncated')
24
19
  : undefined;
20
+ // TODO truncate with the AST instead of the string ?
25
21
  if (truncated) {
26
22
  finalContent = (0, blogUtils_1.truncate)(finalContent, markdownLoaderOptions.truncateMarker);
27
23
  }
package/lib/options.js CHANGED
@@ -42,6 +42,8 @@ exports.DEFAULT_OPTIONS = {
42
42
  showLastUpdateTime: false,
43
43
  showLastUpdateAuthor: false,
44
44
  processBlogPosts: async () => undefined,
45
+ onInlineTags: 'warn',
46
+ tags: undefined,
45
47
  };
46
48
  const PluginOptionSchema = utils_validation_1.Joi.object({
47
49
  path: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.path),
@@ -111,6 +113,13 @@ const PluginOptionSchema = utils_validation_1.Joi.object({
111
113
  processBlogPosts: utils_validation_1.Joi.function()
112
114
  .optional()
113
115
  .default(() => exports.DEFAULT_OPTIONS.processBlogPosts),
116
+ onInlineTags: utils_validation_1.Joi.string()
117
+ .equal('ignore', 'log', 'warn', 'throw')
118
+ .default(exports.DEFAULT_OPTIONS.onInlineTags),
119
+ tags: utils_validation_1.Joi.string()
120
+ .disallow('')
121
+ .allow(null, false)
122
+ .default(() => exports.DEFAULT_OPTIONS.tags),
114
123
  }).default(exports.DEFAULT_OPTIONS);
115
124
  function validateOptions({ validate, options, }) {
116
125
  const validatedOptions = validate(PluginOptionSchema, options);
package/lib/props.js CHANGED
@@ -7,6 +7,7 @@ function toTagsProp({ blogTags }) {
7
7
  .map((tag) => ({
8
8
  label: tag.label,
9
9
  permalink: tag.permalink,
10
+ description: tag.description,
10
11
  count: tag.items.length,
11
12
  }));
12
13
  }
@@ -15,6 +16,7 @@ function toTagProp({ blogTagsListPath, tag, }) {
15
16
  return {
16
17
  label: tag.label,
17
18
  permalink: tag.permalink,
19
+ description: tag.description,
18
20
  allTagsPath: blogTagsListPath,
19
21
  count: tag.items.length,
20
22
  unlisted: tag.unlisted,
package/lib/types.d.ts CHANGED
@@ -4,15 +4,8 @@
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
- import type { BrokenMarkdownLink, ContentPaths } from '@docusaurus/utils';
7
+ import type { ContentPaths } from '@docusaurus/utils';
8
8
  export type BlogContentPaths = ContentPaths;
9
- export type BlogBrokenMarkdownLink = BrokenMarkdownLink<BlogContentPaths>;
10
9
  export type BlogMarkdownLoaderOptions = {
11
- siteDir: string;
12
- contentPaths: BlogContentPaths;
13
10
  truncateMarker: RegExp;
14
- sourceToPermalink: {
15
- [aliasedPath: string]: string;
16
- };
17
- onBrokenMarkdownLink: (brokenMarkdownLink: BlogBrokenMarkdownLink) => void;
18
11
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docusaurus/plugin-content-blog",
3
- "version": "3.3.2",
3
+ "version": "3.4.0",
4
4
  "description": "Blog plugin for Docusaurus.",
5
5
  "main": "lib/index.js",
6
6
  "types": "src/plugin-content-blog.d.ts",
@@ -31,13 +31,13 @@
31
31
  },
32
32
  "license": "MIT",
33
33
  "dependencies": {
34
- "@docusaurus/core": "3.3.2",
35
- "@docusaurus/logger": "3.3.2",
36
- "@docusaurus/mdx-loader": "3.3.2",
37
- "@docusaurus/types": "3.3.2",
38
- "@docusaurus/utils": "3.3.2",
39
- "@docusaurus/utils-common": "3.3.2",
40
- "@docusaurus/utils-validation": "3.3.2",
34
+ "@docusaurus/core": "3.4.0",
35
+ "@docusaurus/logger": "3.4.0",
36
+ "@docusaurus/mdx-loader": "3.4.0",
37
+ "@docusaurus/types": "3.4.0",
38
+ "@docusaurus/utils": "3.4.0",
39
+ "@docusaurus/utils-common": "3.4.0",
40
+ "@docusaurus/utils-validation": "3.4.0",
41
41
  "cheerio": "^1.0.0-rc.12",
42
42
  "feed": "^4.2.2",
43
43
  "fs-extra": "^11.1.1",
@@ -59,5 +59,5 @@
59
59
  "devDependencies": {
60
60
  "@total-typescript/shoehorn": "^0.1.2"
61
61
  },
62
- "gitHead": "bc638d674bfbde1e254ef306697f47e764b5e107"
62
+ "gitHead": "49e9a2143274a8dd795659b417b470bc42abbd6e"
63
63
  }