feat(v2): add meta RSS/Atom feed links to head (#2000)

Co-authored-by: Endi <endiliey@gmail.com>

* feat(v2): add meta RSS/Atom feed links to head

* refactor(v2): use new API

* Better typing

* fix typing
This commit is contained in:
Alexey Pyltsyn 2019-11-30 19:05:53 +03:00 committed by Endi
parent 2297ae9f57
commit 3caff0d221
2 changed files with 77 additions and 10 deletions

View file

@ -17,6 +17,7 @@ import {
BlogItemsToModules,
TagsModule,
BlogPaginated,
FeedType,
} from './types';
import {
LoadContext,
@ -24,6 +25,7 @@ import {
ConfigureWebpackUtils,
Props,
Plugin,
HtmlTags,
} from '@docusaurus/types';
import {Configuration, Loader} from 'webpack';
import {generateBlogFeed, generateBlogPosts} from './blogUtils';
@ -42,6 +44,26 @@ const DEFAULT_OPTIONS: PluginOptions = {
truncateMarker: /<!--\s*(truncate)\s*-->/, // string or regex
};
function assertFeedTypes(val: any): asserts val is FeedType {
if (typeof val !== 'string' && !['rss', 'atom', 'all'].includes(val)) {
throw new Error(
`Invalid feedOptions type: ${val}. It must be either 'rss', 'atom', or 'all'`,
);
}
}
const getFeedTypes = (type?: FeedType) => {
assertFeedTypes(type);
let feedTypes: ('rss' | 'atom')[] = [];
if (type === 'all') {
feedTypes = ['rss', 'atom'];
} else {
feedTypes.push(type);
}
return feedTypes;
};
export default function pluginContentBlog(
context: LoadContext,
opts: Partial<PluginOptions>,
@ -389,19 +411,13 @@ export default function pluginContentBlog(
return;
}
const {
feedOptions: {type: feedType},
} = options;
const feed = await generateBlogFeed(context, options);
if (!feed) {
return;
}
let feedTypes = [];
if (feedType === 'all') {
feedTypes = ['rss', 'atom'];
} else {
feedTypes.push(feedType);
}
const feedTypes = getFeedTypes(options.feedOptions?.type);
await Promise.all(
feedTypes.map(feedType => {
@ -419,5 +435,54 @@ export default function pluginContentBlog(
}),
);
},
injectHtmlTags() {
if (!options.feedOptions) {
return {};
}
const feedTypes = getFeedTypes(options.feedOptions?.type);
const {
siteConfig: {title},
baseUrl,
} = context;
const feedsConfig = {
rss: {
type: 'application/rss+xml',
path: 'blog/rss.xml',
title: `${title} Blog RSS Feed`,
},
atom: {
type: 'application/atom+xml',
path: 'blog/atom.xml',
title: `${title} Blog Atom Feed`,
},
};
const headTags: HtmlTags = [];
feedTypes.map(feedType => {
const feedConfig = feedsConfig[feedType] || {};
if (!feedsConfig) {
return;
}
const {type, path, title} = feedConfig;
headTags.push({
tagName: 'link',
attributes: {
rel: 'alternate',
type,
href: normalizeUrl([baseUrl, path]),
title,
},
});
});
return {
headTags,
};
},
};
}

View file

@ -17,6 +17,8 @@ export interface DateLink {
link: string;
}
export type FeedType = 'rss' | 'atom' | 'all';
export interface PluginOptions {
path: string;
routeBasePath: string;
@ -30,7 +32,7 @@ export interface PluginOptions {
rehypePlugins: string[];
truncateMarker: RegExp | string;
feedOptions?: {
type: 'rss' | 'atom' | 'all';
type: FeedType;
title?: string;
description?: string;
copyright: string;