Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(v2): feature/docs slug frontmatter (v2) #2771

Merged
merged 10 commits into from
Jun 2, 2020
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
slug: hello/super
---

Lorem
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
id: baz
title: baz
slug: bazSlug.html
---

## Images
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
---
slug: barSlug
---
This is `next` version of bar.
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
---
slug: barSlug
---
Bar `1.0.0` !
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Object {
"type": "link",
},
Object {
"href": "/docs/foo/baz",
"href": "/docs/foo/bazSlug.html",
"label": "baz",
"type": "link",
},
Expand Down Expand Up @@ -83,7 +83,7 @@ Array [
"modules": Object {
"content": "@site/docs/foo/baz.md",
},
"path": "/docs/foo/baz",
"path": "/docs/foo/bazSlug.html",
},
Object {
"component": "@theme/DocItem",
Expand Down Expand Up @@ -157,7 +157,7 @@ Array [
"modules": Object {
"content": "@site/versioned_docs/version-1.0.0/foo/bar.md",
},
"path": "/docs/1.0.0/foo/bar",
"path": "/docs/1.0.0/foo/barSlug",
},
Object {
"component": "@theme/DocItem",
Expand Down Expand Up @@ -191,7 +191,7 @@ Array [
"modules": Object {
"content": "@site/docs/foo/bar.md",
},
"path": "/docs/next/foo/bar",
"path": "/docs/next/foo/barSlug",
},
Object {
"component": "@theme/DocItem",
Expand Down Expand Up @@ -238,7 +238,7 @@ Object {
Object {
"items": Array [
Object {
"href": "/docs/next/foo/bar",
"href": "/docs/next/foo/barSlug",
"label": "bar",
"type": "link",
},
Expand All @@ -262,7 +262,7 @@ Object {
Object {
"items": Array [
Object {
"href": "/docs/1.0.0/foo/bar",
"href": "/docs/1.0.0/foo/barSlug",
"label": "bar",
"type": "link",
},
Expand Down Expand Up @@ -321,7 +321,7 @@ Object {
Object {
"items": Array [
Object {
"href": "/docs/1.0.0/foo/bar",
"href": "/docs/1.0.0/foo/barSlug",
"label": "bar",
"type": "link",
},
Expand All @@ -348,7 +348,7 @@ Object {
],
},
"permalinkToSidebar": Object {
"/docs/1.0.0/foo/bar": "version-1.0.0/docs",
"/docs/1.0.0/foo/barSlug": "version-1.0.0/docs",
"/docs/1.0.0/foo/baz": "version-1.0.0/docs",
"/docs/1.0.0/hello": "version-1.0.0/docs",
},
Expand Down Expand Up @@ -399,7 +399,7 @@ Object {
Object {
"items": Array [
Object {
"href": "/docs/next/foo/bar",
"href": "/docs/next/foo/barSlug",
"label": "bar",
"type": "link",
},
Expand All @@ -421,7 +421,7 @@ Object {
],
},
"permalinkToSidebar": Object {
"/docs/next/foo/bar": "docs",
"/docs/next/foo/barSlug": "docs",
"/docs/next/hello": "docs",
},
"version": "next",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ describe('simple website', () => {
permalink: '/docs/hello',
previous: {
title: 'baz',
permalink: '/docs/foo/baz',
permalink: '/docs/foo/bazSlug.html',
},
sidebar: 'docs',
source: path.join('@site', pluginPath, 'hello.md'),
Expand All @@ -175,7 +175,7 @@ describe('simple website', () => {
id: 'foo/bar',
next: {
title: 'baz',
permalink: '/docs/foo/baz',
permalink: '/docs/foo/bazSlug.html',
},
permalink: '/docs/foo/bar',
sidebar: 'docs',
Expand Down Expand Up @@ -300,7 +300,7 @@ describe('versioned website', () => {
expect(docsMetadata['version-1.0.1/foo/baz']).toBeUndefined();
expect(docsMetadata['foo/bar']).toEqual({
id: 'foo/bar',
permalink: '/docs/next/foo/bar',
permalink: '/docs/next/foo/barSlug',
source: path.join('@site', routeBasePath, 'foo', 'bar.md'),
title: 'bar',
description: 'This is next version of bar.',
Expand All @@ -321,7 +321,7 @@ describe('versioned website', () => {
sidebar: 'docs',
previous: {
title: 'bar',
permalink: '/docs/next/foo/bar',
permalink: '/docs/next/foo/barSlug',
},
});
expect(docsMetadata['version-1.0.1/hello']).toEqual({
Expand Down Expand Up @@ -363,7 +363,7 @@ describe('versioned website', () => {
},
previous: {
title: 'bar',
permalink: '/docs/1.0.0/foo/bar',
permalink: '/docs/1.0.0/foo/barSlug',
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ describe('simple site', () => {

expect(data).toEqual({
id: 'foo/baz',
permalink: '/docs/foo/baz',
permalink: '/docs/foo/bazSlug.html',
source: path.join('@site', routeBasePath, source),
title: 'baz',
editUrl:
Expand Down Expand Up @@ -172,7 +172,7 @@ describe('simple site', () => {
});

test('docs with invalid id', async () => {
const badSiteDir = path.join(fixtureDir, 'bad-site');
const badSiteDir = path.join(fixtureDir, 'bad-id-site');
const options = {
routeBasePath,
};
Expand All @@ -189,6 +189,25 @@ describe('simple site', () => {
),
);
});

test('docs with invalid slug', async () => {
const badSiteDir = path.join(fixtureDir, 'bad-slug-site');
const options = {
routeBasePath,
};

return processMetadata({
source: 'invalid-slug.md',
refDir: path.join(badSiteDir, 'docs'),
context,
options,
env,
}).catch((e) =>
expect(e).toMatchInlineSnapshot(
`[Error: Document slug cannot include "/".]`,
),
);
});
});

describe('versioned site', () => {
Expand Down Expand Up @@ -225,7 +244,7 @@ describe('versioned site', () => {

expect(dataA).toEqual({
id: 'foo/bar',
permalink: '/docs/next/foo/bar',
permalink: '/docs/next/foo/barSlug',
source: path.join('@site', routeBasePath, sourceA),
title: 'bar',
description: 'This is next version of bar.',
Expand Down Expand Up @@ -283,7 +302,7 @@ describe('versioned site', () => {

expect(dataA).toEqual({
id: 'version-1.0.0/foo/bar',
permalink: '/docs/1.0.0/foo/bar',
permalink: '/docs/1.0.0/foo/barSlug',
source: path.join('@site', path.relative(siteDir, versionedDir), sourceA),
title: 'bar',
description: 'Bar 1.0.0 !',
Expand Down
14 changes: 10 additions & 4 deletions packages/docusaurus-plugin-content-docs/src/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,18 @@ export default async function processMetadata({
// Default base id is the file name.
const baseID: string =
frontMatter.id || path.basename(source, path.extname(source));

if (baseID.includes('/')) {
throw new Error('Document id cannot include "/".');
}

// Append subdirectory as part of id.
const baseSlug: string = frontMatter.slug || baseID;
if (baseSlug.includes('/')) {
throw new Error('Document slug cannot include "/".');
}

// Append subdirectory as part of id/slug.
const id = dirName !== '.' ? `${dirName}/${baseID}` : baseID;
const slug = dirName !== '.' ? `${dirName}/${baseSlug}` : baseSlug;
slorber marked this conversation as resolved.
Show resolved Hide resolved

// Default title is the id.
const title: string = frontMatter.title || baseID;
Expand All @@ -114,8 +119,9 @@ export default async function processMetadata({
// The last portion of the url path. Eg: 'foo/bar', 'bar'.
const routePath =
version && version !== 'next'
? id.replace(new RegExp(`^version-${version}/`), '')
: id;
? slug.replace(new RegExp(`^version-${version}/`), '')
: slug;

const permalink = normalizeUrl([
baseUrl,
routeBasePath,
Expand Down
12 changes: 11 additions & 1 deletion website/docs/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ website # Root directory of your site
└── hello.md
```

However, the last part of the `id` can be defined by user in the front matter. For example, if `guide/hello.md`'s content is defined as below, its final `id` is `guide/part1`.
However, the **last part** of the `id` can be defined by user in the front matter. For example, if `guide/hello.md`'s content is defined as below, its final `id` is `guide/part1`.

```yml
---
Expand All @@ -29,6 +29,16 @@ id: part1
Lorem ipsum
```

If you want more control over the last part of the document url, it is possible to add a `slug` (defaults to the id).
slorber marked this conversation as resolved.
Show resolved Hide resolved

```yml
---
id: part1
slug: part1.html
---
Lorem ipsum
```

## Home page docs

Using the `homePageId` property, you can create a home page of your docs. To do this, you can create a new document, especially for this purpose with the id as `_index`, or you could specify an existing document id.
Expand Down