mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-29 08:57:03 +02:00
fix(content-blog): temporarily swallow feed mdxToHtml errors + feed refactor (#5753)
This commit is contained in:
parent
fd41239f4f
commit
29d13351a4
9 changed files with 234 additions and 109 deletions
129
packages/docusaurus-plugin-content-blog/src/feed.ts
Normal file
129
packages/docusaurus-plugin-content-blog/src/feed.ts
Normal file
|
@ -0,0 +1,129 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {Feed, Author as FeedAuthor} from 'feed';
|
||||
import {PluginOptions, Author, BlogPost, FeedType} from './types';
|
||||
import {normalizeUrl, mdxToHtml} from '@docusaurus/utils';
|
||||
import {DocusaurusConfig} from '@docusaurus/types';
|
||||
import path from 'path';
|
||||
import fs from 'fs-extra';
|
||||
|
||||
// TODO this is temporary until we handle mdxToHtml better
|
||||
// It's hard to convert reliably JSX/require calls to an html feed content
|
||||
// See https://github.com/facebook/docusaurus/issues/5664
|
||||
function mdxToFeedContent(mdxContent: string): string | undefined {
|
||||
try {
|
||||
return mdxToHtml(mdxContent);
|
||||
} catch (e) {
|
||||
// TODO will we need a plugin option to configure how to handle such an error
|
||||
// Swallow the error on purpose for now, until we understand better the problem space
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export async function generateBlogFeed({
|
||||
blogPosts,
|
||||
options,
|
||||
siteConfig,
|
||||
}: {
|
||||
blogPosts: BlogPost[];
|
||||
options: PluginOptions;
|
||||
siteConfig: DocusaurusConfig;
|
||||
}): Promise<Feed | null> {
|
||||
if (!blogPosts.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {feedOptions, routeBasePath} = options;
|
||||
const {url: siteUrl, baseUrl, title, favicon} = siteConfig;
|
||||
const blogBaseUrl = normalizeUrl([siteUrl, baseUrl, routeBasePath]);
|
||||
|
||||
const updated =
|
||||
(blogPosts[0] && blogPosts[0].metadata.date) ||
|
||||
new Date('2015-10-25T16:29:00.000-07:00'); // weird legacy magic date
|
||||
|
||||
const feed = new Feed({
|
||||
id: blogBaseUrl,
|
||||
title: feedOptions.title || `${title} Blog`,
|
||||
updated,
|
||||
language: feedOptions.language,
|
||||
link: blogBaseUrl,
|
||||
description: feedOptions.description || `${siteConfig.title} Blog`,
|
||||
favicon: favicon ? normalizeUrl([siteUrl, baseUrl, favicon]) : undefined,
|
||||
copyright: feedOptions.copyright,
|
||||
});
|
||||
|
||||
function toFeedAuthor(author: Author): FeedAuthor {
|
||||
// TODO ask author emails?
|
||||
// RSS feed requires email to render authors
|
||||
return {name: author.name, link: author.url};
|
||||
}
|
||||
|
||||
blogPosts.forEach((post) => {
|
||||
const {
|
||||
id,
|
||||
metadata: {title: metadataTitle, permalink, date, description, authors},
|
||||
} = post;
|
||||
feed.addItem({
|
||||
title: metadataTitle,
|
||||
id,
|
||||
link: normalizeUrl([siteUrl, permalink]),
|
||||
date,
|
||||
description,
|
||||
content: mdxToFeedContent(post.content),
|
||||
author: authors.map(toFeedAuthor),
|
||||
});
|
||||
});
|
||||
|
||||
return feed;
|
||||
}
|
||||
|
||||
async function createBlogFeedFile({
|
||||
feed,
|
||||
feedType,
|
||||
filePath,
|
||||
}: {
|
||||
feed: Feed;
|
||||
feedType: FeedType;
|
||||
filePath: string;
|
||||
}) {
|
||||
const feedContent = feedType === 'rss' ? feed.rss2() : feed.atom1();
|
||||
try {
|
||||
await fs.outputFile(filePath, feedContent);
|
||||
} catch (err) {
|
||||
throw new Error(`Generating ${feedType} feed failed: ${err}.`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function createBlogFeedFiles({
|
||||
blogPosts,
|
||||
options,
|
||||
siteConfig,
|
||||
outDir,
|
||||
}: {
|
||||
blogPosts: BlogPost[];
|
||||
options: PluginOptions;
|
||||
siteConfig: DocusaurusConfig;
|
||||
outDir: string;
|
||||
}): Promise<void> {
|
||||
const feed = await generateBlogFeed({blogPosts, options, siteConfig});
|
||||
|
||||
const feedTypes = options.feedOptions.type;
|
||||
if (!feed || !feedTypes) {
|
||||
return;
|
||||
}
|
||||
|
||||
await Promise.all(
|
||||
feedTypes.map(async function (feedType) {
|
||||
await createBlogFeedFile({
|
||||
feed,
|
||||
feedType,
|
||||
filePath: path.join(outDir, options.routeBasePath, `${feedType}.xml`),
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue