feat(v2): blog support date front matter (#1702)

* feat(v2): blog support date front matter

* feat(v2): blog support date front matter

* feat(v2): blog support date front matter

* feat(v2): blog support date front matter

* Update CHANGELOG-2.x.md
This commit is contained in:
陈杨文 2019-07-27 19:03:14 +08:00 committed by Endi
parent d17a1ea9e3
commit 95ace0e4eb
6 changed files with 117 additions and 17 deletions

View file

@ -2,6 +2,7 @@
## Unreleased ## Unreleased
- Add `date` frontMatter support for blog plugin
- Add `truncateMarker` option to blog plugin, support string or regex. - Add `truncateMarker` option to blog plugin, support string or regex.
- Webpack `optimization.removeAvailableModules` is now disabled for performance gain. See https://github.com/webpack/webpack/releases/tag/v4.38.0 for more context. - Webpack `optimization.removeAvailableModules` is now disabled for performance gain. See https://github.com/webpack/webpack/releases/tag/v4.38.0 for more context.

View file

@ -0,0 +1,5 @@
---
title: Happy 1st Birthday Slash!
---
pattern name

View file

@ -0,0 +1,5 @@
---
date: 2019-01-01
---
date inside front matter

View file

@ -0,0 +1,76 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import fs from 'fs-extra';
import path from 'path';
import pluginContentBlog from '../index';
describe('loadBlog', () => {
test('simple website', async () => {
const siteDir = path.join(__dirname, '__fixtures__', 'website');
const siteConfig = {
title: 'Hello',
baseUrl: '/',
url: 'https://docusaurus.io',
};
const pluginPath = 'blog';
const plugin = pluginContentBlog(
{
siteDir,
siteConfig,
},
{
path: 'blog',
},
);
const {blogPosts} = await plugin.loadContent();
expect(
blogPosts.find(v => v.metadata.title === 'date-matter').metadata,
).toEqual({
permalink: '/blog/2019/01/01/date-matter',
source: path.join('@site', pluginPath, 'date-matter.md'),
title: 'date-matter',
description: `date inside front matter`,
date: new Date('2019-01-01'),
tags: [],
});
expect(
blogPosts.find(v => v.metadata.title === 'Happy 1st Birthday Slash!')
.metadata,
).toEqual({
permalink: '/blog/2018/12/14/Happy-First-Birthday-Slash',
source: path.join(
'@site',
pluginPath,
'2018-12-14-Happy-First-Birthday-Slash.md',
),
title: 'Happy 1st Birthday Slash!',
description: `pattern name`,
date: new Date('2018-12-14'),
tags: [],
});
const noDateSource = path.join('@site', pluginPath, 'no date.md');
const noDateSourceBirthTime = (await fs.stat(
noDateSource.replace('@site', siteDir),
)).birthtime;
expect(
blogPosts.find(v => v.metadata.title === 'no date').metadata,
).toEqual({
permalink: `/blog/${noDateSourceBirthTime
.toISOString()
.substr(0, '2019-01-01'.length)
.replace(/-/g, '/')}/no date`,
source: noDateSource,
title: 'no date',
description: `no date`,
date: noDateSourceBirthTime,
tags: [],
});
});
});

View file

@ -11,13 +11,15 @@ const _ = require('lodash');
const path = require('path'); const path = require('path');
const {parse, normalizeUrl, docuHash} = require('@docusaurus/utils'); const {parse, normalizeUrl, docuHash} = require('@docusaurus/utils');
// TODO: Use a better slugify function that doesn't rely on a specific file extension. // YYYY-MM-DD-{name}.mdx?
function fileToUrl(fileName) { // prefer named capture, but old node version do not support
return fileName const FILENAME_PATTERN = /^(\d{4}-\d{1,2}-\d{1,2})-?(.*?).mdx?$/;
.replace('-', '/')
.replace('-', '/') function toUrl({date, link}) {
.replace('-', '/') return `${date
.replace(/\.mdx?$/, ''); .toISOString()
.substring(0, '2019-01-01'.length)
.replace(/-/g, '/')}/${link}`;
} }
const DEFAULT_OPTIONS = { const DEFAULT_OPTIONS = {
@ -70,30 +72,40 @@ module.exports = function(context, opts) {
const source = path.join(blogDir, relativeSource); const source = path.join(blogDir, relativeSource);
const aliasedSource = `@site/${path.relative(siteDir, source)}`; const aliasedSource = `@site/${path.relative(siteDir, source)}`;
const blogFileName = path.basename(relativeSource); const blogFileName = path.basename(relativeSource);
// Extract, YYYY, MM, DD from the file name.
const filePathDateArr = blogFileName.split('-');
const date = new Date(
`${filePathDateArr[0]}-${filePathDateArr[1]}-${
filePathDateArr[2]
}T06:00:00.000Z`,
);
const fileString = await fs.readFile(source, 'utf-8'); const fileString = await fs.readFile(source, 'utf-8');
const {frontMatter, excerpt} = parse(fileString); const {frontMatter, excerpt} = parse(fileString);
let date;
// extract date and title from filename
const match = blogFileName.match(FILENAME_PATTERN);
let linkName = blogFileName.replace(/\.mdx?$/, '');
if (match) {
const [, dateString, name] = match;
date = new Date(dateString);
linkName = name;
}
// prefer usedefined date
if (frontMatter.date) {
date = new Date(frontMatter.date);
}
// use file create time for blog
date = date || (await fs.stat(source)).birthtime;
frontMatter.title = frontMatter.title || linkName;
blogPosts.push({ blogPosts.push({
id: frontMatter.id || blogFileName, id: frontMatter.id || frontMatter.title,
metadata: { metadata: {
permalink: normalizeUrl([ permalink: normalizeUrl([
baseUrl, baseUrl,
routeBasePath, routeBasePath,
frontMatter.id || fileToUrl(blogFileName), frontMatter.id || toUrl({date, link: linkName}),
]), ]),
source: aliasedSource, source: aliasedSource,
description: frontMatter.description || excerpt, description: frontMatter.description || excerpt,
date, date,
tags: frontMatter.tags, tags: frontMatter.tags,
title: frontMatter.title || blogFileName, title: frontMatter.title,
}, },
}); });
}), }),