feat(v2): add blog post estimated reading time (#2531)

* feat: add estimated reading time to blog posts

* docs: add showReadingTime on plugin docs

* test: update plugin-content-blog tests to cover readingTime

* Update index.js

* Update using-plugins.md

* Update index.js

Co-authored-by: Yangshun Tay <tay.yang.shun@gmail.com>
This commit is contained in:
José Renan 2020-04-05 04:08:42 -03:00 committed by GitHub
parent c576faac73
commit 95fdfe7e15
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 25 additions and 4 deletions

View file

@ -20,7 +20,8 @@
"fs-extra": "^8.1.0",
"globby": "^10.0.1",
"loader-utils": "^1.2.3",
"lodash.kebabcase": "^4.1.1"
"lodash.kebabcase": "^4.1.1",
"reading-time": "^1.2.0"
},
"peerDependencies": {
"@docusaurus/core": "^2.0.0",

View file

@ -51,6 +51,7 @@ describe('loadBlog', () => {
...{prevItem: undefined},
}).toEqual({
permalink: '/blog/2019/01/01/date-matter',
readingTime: 0.02,
source: path.join('@site', pluginPath, 'date-matter.md'),
title: 'date-matter',
description: `date inside front matter`,
@ -68,6 +69,7 @@ describe('loadBlog', () => {
.metadata,
).toEqual({
permalink: '/blog/2018/12/14/Happy-First-Birthday-Slash',
readingTime: 0.01,
source: path.join(
'@site',
pluginPath,
@ -89,6 +91,7 @@ describe('loadBlog', () => {
...{prevItem: undefined},
}).toEqual({
permalink: noDatePermalink,
readingTime: 0.01,
source: noDateSource,
title: 'no date',
description: `no date`,

View file

@ -8,6 +8,7 @@
import fs from 'fs-extra';
import globby from 'globby';
import path from 'path';
import readingTime from 'reading-time';
import {Feed} from 'feed';
import {PluginOptions, BlogPost, DateLink} from './types';
import {parse, normalizeUrl, aliasedSitePath} from '@docusaurus/utils';
@ -85,7 +86,7 @@ export async function generateBlogPosts(
{siteConfig, siteDir}: LoadContext,
options: PluginOptions,
) {
const {include, routeBasePath, truncateMarker} = options;
const {include, routeBasePath, truncateMarker, showReadingTime} = options;
if (!fs.existsSync(blogDir)) {
return [];
@ -144,6 +145,9 @@ export async function generateBlogPosts(
date,
tags: frontMatter.tags,
title: frontMatter.title,
readingTime: showReadingTime
? readingTime(content).minutes
: undefined,
truncated: truncateMarker?.test(content) || false,
},
});

View file

@ -40,6 +40,7 @@ const DEFAULT_OPTIONS: PluginOptions = {
blogPostComponent: '@theme/BlogPostPage',
blogTagsListComponent: '@theme/BlogTagsListPage',
blogTagsPostsComponent: '@theme/BlogTagsPostsPage',
showReadingTime: true,
remarkPlugins: [],
rehypePlugins: [],
truncateMarker: /<!--\s*(truncate)\s*-->/, // Regex.

View file

@ -31,6 +31,7 @@ export interface PluginOptions {
remarkPlugins: string[];
rehypePlugins: string[];
truncateMarker: RegExp;
showReadingTime: boolean;
feedOptions?: {
type: FeedType;
title?: string;
@ -77,6 +78,7 @@ export interface MetaData {
date: Date;
tags: (Tag | string)[];
title: string;
readingTime?: number;
prevItem?: Paginator;
nextItem?: Paginator;
truncated: boolean;

View file

@ -37,7 +37,7 @@ function BlogPostItem(props) {
truncated,
isBlogPostPage = false,
} = props;
const {date, permalink, tags} = metadata;
const {date, permalink, tags, readingTime} = metadata;
const {author, title} = frontMatter;
const authorURL = frontMatter.author_url || frontMatter.authorURL;
@ -60,7 +60,8 @@ function BlogPostItem(props) {
</TitleHeading>
<div className="margin-vert--md">
<time dateTime={date} className={styles.blogPostDate}>
{month} {day}, {year}
{month} {day}, {year}{' '}
{readingTime && <> · {Math.ceil(readingTime)} min read</>}
</time>
</div>
<div className="avatar margin-vert--md">

View file

@ -174,6 +174,10 @@ module.exports = {
* Truncate marker, can be a regex or string.
*/
truncateMarker: /<!--\s*(truncate)\s*-->/,
/**
* Show estimated reading time for the blog post.
*/
showReadingTime: true,
/**
* Blog feed
* If feedOptions is undefined, no rss feed will be generated

View file

@ -13933,6 +13933,11 @@ readdirp@~3.3.0:
dependencies:
picomatch "^2.0.7"
reading-time@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/reading-time/-/reading-time-1.2.0.tgz#ced71c06715762f805506328dcc1fd45d8249ac4"
integrity sha512-5b4XmKK4MEss63y0Lw0vn0Zn6G5kiHP88mUnD8UeEsyORj3sh1ghTH0/u6m1Ax9G2F4wUZrknlp6WlIsCvoXVA==
realpath-native@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c"