mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-18 03:26:57 +02:00
feat(v2): blog slug frontmatter (#3284)
This commit is contained in:
parent
0f357606cd
commit
3ea2f8cfde
16 changed files with 107 additions and 27 deletions
|
@ -34,6 +34,24 @@ authorTwitter: JoelMarcey
|
||||||
Lorem Ipsum...
|
Lorem Ipsum...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Adding slug will override the url of the blog post.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
---
|
||||||
|
slug: introducing-docusaurus
|
||||||
|
title: Introducing Docusaurus
|
||||||
|
author: Joel Marcey
|
||||||
|
authorURL: http://twitter.com/JoelMarcey
|
||||||
|
authorFBID: 611217057
|
||||||
|
authorTwitter: JoelMarcey
|
||||||
|
---
|
||||||
|
Lorem Ipsum...
|
||||||
|
```
|
||||||
|
|
||||||
|
Will be available at `https://website/blog/introducing-docusaurus`
|
||||||
|
|
||||||
## Header Options
|
## Header Options
|
||||||
|
|
||||||
The only required field is `title`; however, we provide options to add author information to your blog post as well along with other options.
|
The only required field is `title`; however, we provide options to add author information to your blog post as well along with other options.
|
||||||
|
@ -43,6 +61,7 @@ The only required field is `title`; however, we provide options to add author in
|
||||||
- `authorFBID` - The Facebook profile ID that is used to fetch the profile picture.
|
- `authorFBID` - The Facebook profile ID that is used to fetch the profile picture.
|
||||||
- `authorImageURL` - The URL to the author's image. (Note: If you use both `authorFBID` and `authorImageURL`, `authorFBID` will take precedence. Don't include `authorFBID` if you want `authorImageURL` to appear.)
|
- `authorImageURL` - The URL to the author's image. (Note: If you use both `authorFBID` and `authorImageURL`, `authorFBID` will take precedence. Don't include `authorFBID` if you want `authorImageURL` to appear.)
|
||||||
- `title` - The blog post title.
|
- `title` - The blog post title.
|
||||||
|
- `slug` - The blog post url slug. Example: `/blog/my-test-slug`. When not specified, the blog url slug will be extracted from the file name.
|
||||||
- `unlisted` - The post will be accessible by directly visiting the URL but will not show up in the sidebar in the final build; during local development, the post will still be listed. Useful in situations where you want to share a WIP post with others for feedback.
|
- `unlisted` - The post will be accessible by directly visiting the URL but will not show up in the sidebar in the final build; during local development, the post will still be listed. Useful in situations where you want to share a WIP post with others for feedback.
|
||||||
|
|
||||||
## Summary Truncation
|
## Summary Truncation
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
id: hola
|
slug: hola
|
||||||
title: Hola
|
title: Hola
|
||||||
author: Gao Wei
|
author: Gao Wei
|
||||||
author_title: Docusaurus Core Team
|
author_title: Docusaurus Core Team
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
id: hello-world
|
slug: hello-world
|
||||||
title: Hello
|
title: Hello
|
||||||
author: Endilie Yacop Sucipto
|
author: Endilie Yacop Sucipto
|
||||||
author_title: Maintainer of Docusaurus
|
author_title: Maintainer of Docusaurus
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
id: welcome
|
slug: welcome
|
||||||
title: Welcome
|
title: Welcome
|
||||||
author: Yangshun Tay
|
author: Yangshun Tay
|
||||||
author_title: Front End Engineer @ Facebook
|
author_title: Front End Engineer @ Facebook
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
id: hola
|
slug: hola
|
||||||
title: Hola
|
title: Hola
|
||||||
author: Gao Wei
|
author: Gao Wei
|
||||||
author_title: Docusaurus Core Team
|
author_title: Docusaurus Core Team
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
id: hello-world
|
slug: hello-world
|
||||||
title: Hello
|
title: Hello
|
||||||
author: Endilie Yacop Sucipto
|
author: Endilie Yacop Sucipto
|
||||||
author_title: Maintainer of Docusaurus
|
author_title: Maintainer of Docusaurus
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
id: welcome
|
slug: welcome
|
||||||
title: Welcome
|
title: Welcome
|
||||||
author: Yangshun Tay
|
author: Yangshun Tay
|
||||||
author_title: Front End Engineer @ Facebook
|
author_title: Front End Engineer @ Facebook
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
id: hola
|
slug: hola
|
||||||
title: Hola
|
title: Hola
|
||||||
author: Gao Wei
|
author: Gao Wei
|
||||||
author_title: Docusaurus Core Team
|
author_title: Docusaurus Core Team
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
id: hello-world
|
slug: hello-world
|
||||||
title: Hello
|
title: Hello
|
||||||
author: Endilie Yacop Sucipto
|
author: Endilie Yacop Sucipto
|
||||||
author_title: Maintainer of Docusaurus
|
author_title: Maintainer of Docusaurus
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
id: welcome
|
slug: welcome
|
||||||
title: Welcome
|
title: Welcome
|
||||||
author: Yangshun Tay
|
author: Yangshun Tay
|
||||||
author_title: Front End Engineer @ Facebook
|
author_title: Front End Engineer @ Facebook
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
"@docusaurus/utils-validation": "^2.0.0-alpha.61",
|
"@docusaurus/utils-validation": "^2.0.0-alpha.61",
|
||||||
"@hapi/joi": "^17.1.1",
|
"@hapi/joi": "^17.1.1",
|
||||||
"feed": "^4.1.0",
|
"feed": "^4.1.0",
|
||||||
|
"chalk": "^3.0.0",
|
||||||
"fs-extra": "^8.1.0",
|
"fs-extra": "^8.1.0",
|
||||||
"globby": "^10.0.1",
|
"globby": "^10.0.1",
|
||||||
"loader-utils": "^1.2.3",
|
"loader-utils": "^1.2.3",
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
slug: /hey/my super path/héllô
|
||||||
|
title: Complex Slug
|
||||||
|
date: 2020-08-16
|
||||||
|
---
|
||||||
|
|
||||||
|
complex url slug
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
slug: /simple/slug
|
||||||
|
title: Simple Slug
|
||||||
|
date: 2020-08-16
|
||||||
|
---
|
||||||
|
|
||||||
|
simple url slug
|
|
@ -28,14 +28,14 @@ exports[`blogFeed atom shows feed item for each post 1`] = `
|
||||||
<entry>
|
<entry>
|
||||||
<title type=\\"html\\"><![CDATA[draft]]></title>
|
<title type=\\"html\\"><![CDATA[draft]]></title>
|
||||||
<id>draft</id>
|
<id>draft</id>
|
||||||
<link href=\\"https://docusaurus.io/blog/2020/02/27/draft\\"/>
|
<link href=\\"https://docusaurus.io/blog/draft\\"/>
|
||||||
<updated>2020-02-27T00:00:00.000Z</updated>
|
<updated>2020-02-27T00:00:00.000Z</updated>
|
||||||
<summary type=\\"html\\"><![CDATA[this post should not be published yet]]></summary>
|
<summary type=\\"html\\"><![CDATA[this post should not be published yet]]></summary>
|
||||||
</entry>
|
</entry>
|
||||||
<entry>
|
<entry>
|
||||||
<title type=\\"html\\"><![CDATA[date-matter]]></title>
|
<title type=\\"html\\"><![CDATA[date-matter]]></title>
|
||||||
<id>date-matter</id>
|
<id>date-matter</id>
|
||||||
<link href=\\"https://docusaurus.io/blog/2019/01/01/date-matter\\"/>
|
<link href=\\"https://docusaurus.io/blog/date-matter\\"/>
|
||||||
<updated>2019-01-01T00:00:00.000Z</updated>
|
<updated>2019-01-01T00:00:00.000Z</updated>
|
||||||
<summary type=\\"html\\"><![CDATA[date inside front matter]]></summary>
|
<summary type=\\"html\\"><![CDATA[date inside front matter]]></summary>
|
||||||
</entry>
|
</entry>
|
||||||
|
@ -77,14 +77,14 @@ exports[`blogFeed rss shows feed item for each post 1`] = `
|
||||||
<copyright>Copyright</copyright>
|
<copyright>Copyright</copyright>
|
||||||
<item>
|
<item>
|
||||||
<title><![CDATA[draft]]></title>
|
<title><![CDATA[draft]]></title>
|
||||||
<link>https://docusaurus.io/blog/2020/02/27/draft</link>
|
<link>https://docusaurus.io/blog/draft</link>
|
||||||
<guid>draft</guid>
|
<guid>draft</guid>
|
||||||
<pubDate>Thu, 27 Feb 2020 00:00:00 GMT</pubDate>
|
<pubDate>Thu, 27 Feb 2020 00:00:00 GMT</pubDate>
|
||||||
<description><![CDATA[this post should not be published yet]]></description>
|
<description><![CDATA[this post should not be published yet]]></description>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<title><![CDATA[date-matter]]></title>
|
<title><![CDATA[date-matter]]></title>
|
||||||
<link>https://docusaurus.io/blog/2019/01/01/date-matter</link>
|
<link>https://docusaurus.io/blog/date-matter</link>
|
||||||
<guid>date-matter</guid>
|
<guid>date-matter</guid>
|
||||||
<pubDate>Tue, 01 Jan 2019 00:00:00 GMT</pubDate>
|
<pubDate>Tue, 01 Jan 2019 00:00:00 GMT</pubDate>
|
||||||
<description><![CDATA[date inside front matter]]></description>
|
<description><![CDATA[date inside front matter]]></description>
|
||||||
|
|
|
@ -53,10 +53,6 @@ describe('loadBlog', () => {
|
||||||
const noDateSourceBirthTime = (
|
const noDateSourceBirthTime = (
|
||||||
await fs.stat(noDateSource.replace('@site', siteDir))
|
await fs.stat(noDateSource.replace('@site', siteDir))
|
||||||
).birthtime;
|
).birthtime;
|
||||||
const noDatePermalink = `/blog/${noDateSourceBirthTime
|
|
||||||
.toISOString()
|
|
||||||
.substr(0, '2019-01-01'.length)
|
|
||||||
.replace(/-/g, '/')}/no date`;
|
|
||||||
|
|
||||||
expect({
|
expect({
|
||||||
...blogPosts.find((v) => v.metadata.title === 'date-matter').metadata,
|
...blogPosts.find((v) => v.metadata.title === 'date-matter').metadata,
|
||||||
|
@ -64,7 +60,7 @@ describe('loadBlog', () => {
|
||||||
}).toEqual({
|
}).toEqual({
|
||||||
editUrl:
|
editUrl:
|
||||||
'https://github.com/facebook/docusaurus/edit/master/website-1x/blog/date-matter.md',
|
'https://github.com/facebook/docusaurus/edit/master/website-1x/blog/date-matter.md',
|
||||||
permalink: '/blog/2019/01/01/date-matter',
|
permalink: '/blog/date-matter',
|
||||||
readingTime: 0.02,
|
readingTime: 0.02,
|
||||||
source: path.join('@site', pluginPath, 'date-matter.md'),
|
source: path.join('@site', pluginPath, 'date-matter.md'),
|
||||||
title: 'date-matter',
|
title: 'date-matter',
|
||||||
|
@ -97,7 +93,7 @@ describe('loadBlog', () => {
|
||||||
date: new Date('2018-12-14'),
|
date: new Date('2018-12-14'),
|
||||||
tags: [],
|
tags: [],
|
||||||
prevItem: {
|
prevItem: {
|
||||||
permalink: '/blog/2019/01/01/date-matter',
|
permalink: '/blog/date-matter',
|
||||||
title: 'date-matter',
|
title: 'date-matter',
|
||||||
},
|
},
|
||||||
truncated: false,
|
truncated: false,
|
||||||
|
@ -109,7 +105,7 @@ describe('loadBlog', () => {
|
||||||
}).toEqual({
|
}).toEqual({
|
||||||
editUrl:
|
editUrl:
|
||||||
'https://github.com/facebook/docusaurus/edit/master/website-1x/blog/no date.md',
|
'https://github.com/facebook/docusaurus/edit/master/website-1x/blog/no date.md',
|
||||||
permalink: noDatePermalink,
|
permalink: '/blog/no date',
|
||||||
readingTime: 0.01,
|
readingTime: 0.01,
|
||||||
source: noDateSource,
|
source: noDateSource,
|
||||||
title: 'no date',
|
title: 'no date',
|
||||||
|
@ -118,9 +114,51 @@ describe('loadBlog', () => {
|
||||||
tags: [],
|
tags: [],
|
||||||
prevItem: undefined,
|
prevItem: undefined,
|
||||||
nextItem: {
|
nextItem: {
|
||||||
permalink: '/blog/2020/02/27/draft',
|
permalink: '/blog/hey/my super path/héllô',
|
||||||
|
title: 'Complex Slug',
|
||||||
|
},
|
||||||
|
truncated: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect({
|
||||||
|
...blogPosts.find((v) => v.metadata.title === 'Complex Slug').metadata,
|
||||||
|
...{prevItem: undefined},
|
||||||
|
}).toEqual({
|
||||||
|
editUrl:
|
||||||
|
'https://github.com/facebook/docusaurus/edit/master/website-1x/blog/complex-slug.md',
|
||||||
|
permalink: '/blog/hey/my super path/héllô',
|
||||||
|
readingTime: 0.015,
|
||||||
|
source: path.join('@site', pluginPath, 'complex-slug.md'),
|
||||||
|
title: 'Complex Slug',
|
||||||
|
description: `complex url slug`,
|
||||||
|
prevItem: undefined,
|
||||||
|
nextItem: {
|
||||||
|
permalink: '/blog/simple/slug',
|
||||||
|
title: 'Simple Slug',
|
||||||
|
},
|
||||||
|
date: new Date('2020-08-16'),
|
||||||
|
tags: [],
|
||||||
|
truncated: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect({
|
||||||
|
...blogPosts.find((v) => v.metadata.title === 'Simple Slug').metadata,
|
||||||
|
...{prevItem: undefined},
|
||||||
|
}).toEqual({
|
||||||
|
editUrl:
|
||||||
|
'https://github.com/facebook/docusaurus/edit/master/website-1x/blog/simple-slug.md',
|
||||||
|
permalink: '/blog/simple/slug',
|
||||||
|
readingTime: 0.015,
|
||||||
|
source: path.join('@site', pluginPath, 'simple-slug.md'),
|
||||||
|
title: 'Simple Slug',
|
||||||
|
description: `simple url slug`,
|
||||||
|
prevItem: undefined,
|
||||||
|
nextItem: {
|
||||||
|
permalink: '/blog/draft',
|
||||||
title: 'draft',
|
title: 'draft',
|
||||||
},
|
},
|
||||||
|
date: new Date('2020-08-16'),
|
||||||
|
tags: [],
|
||||||
truncated: false,
|
truncated: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import globby from 'globby';
|
import globby from 'globby';
|
||||||
|
import chalk from 'chalk';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import readingTime from 'reading-time';
|
import readingTime from 'reading-time';
|
||||||
import {Feed} from 'feed';
|
import {Feed} from 'feed';
|
||||||
|
@ -126,6 +127,14 @@ export async function generateBlogPosts(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (frontMatter.id) {
|
||||||
|
console.warn(
|
||||||
|
chalk.yellow(
|
||||||
|
`${blogFileName} - 'id' header option is deprecated. Please use 'slug' option instead.`,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let date;
|
let date;
|
||||||
// Extract date and title from filename.
|
// Extract date and title from filename.
|
||||||
const match = blogFileName.match(FILENAME_PATTERN);
|
const match = blogFileName.match(FILENAME_PATTERN);
|
||||||
|
@ -144,16 +153,15 @@ export async function generateBlogPosts(
|
||||||
|
|
||||||
// Use file create time for blog.
|
// Use file create time for blog.
|
||||||
date = date || (await fs.stat(source)).birthtime;
|
date = date || (await fs.stat(source)).birthtime;
|
||||||
|
|
||||||
|
const slug =
|
||||||
|
frontMatter.slug || (match ? toUrl({date, link: linkName}) : linkName);
|
||||||
frontMatter.title = frontMatter.title || linkName;
|
frontMatter.title = frontMatter.title || linkName;
|
||||||
|
|
||||||
blogPosts.push({
|
blogPosts.push({
|
||||||
id: frontMatter.id || frontMatter.title,
|
id: frontMatter.slug || frontMatter.title,
|
||||||
metadata: {
|
metadata: {
|
||||||
permalink: normalizeUrl([
|
permalink: normalizeUrl([baseUrl, routeBasePath, slug]),
|
||||||
baseUrl,
|
|
||||||
routeBasePath,
|
|
||||||
frontMatter.id || toUrl({date, link: linkName}),
|
|
||||||
]),
|
|
||||||
editUrl: editBlogUrl,
|
editUrl: editBlogUrl,
|
||||||
source: aliasedSource,
|
source: aliasedSource,
|
||||||
description: frontMatter.description || excerpt,
|
description: frontMatter.description || excerpt,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue