mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-05 13:17:23 +02:00
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:
parent
d17a1ea9e3
commit
95ace0e4eb
6 changed files with 117 additions and 17 deletions
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Happy 1st Birthday Slash!
|
||||||
|
---
|
||||||
|
|
||||||
|
pattern name
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
date: 2019-01-01
|
||||||
|
---
|
||||||
|
|
||||||
|
date inside front matter
|
|
@ -0,0 +1 @@
|
||||||
|
no date
|
|
@ -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: [],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -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,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|
Loading…
Add table
Reference in a new issue