mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-29 10:17:55 +02:00
feat(blog): add blog pageBasePath plugin option (#9838)
Co-authored-by: sebastien <lorber.sebastien@gmail.com>
This commit is contained in:
parent
cc7f43580c
commit
70ba9d2d01
8 changed files with 113 additions and 21 deletions
|
@ -23,7 +23,32 @@ title: This post links to another one!
|
|||
[Linked post](/blog/2018/12/14/Happy-First-Birthday-Slash)"
|
||||
`;
|
||||
|
||||
exports[`paginateBlogPosts generates right pages 1`] = `
|
||||
exports[`paginateBlogPosts generates a single page 1`] = `
|
||||
[
|
||||
{
|
||||
"items": [
|
||||
"post1",
|
||||
"post2",
|
||||
"post3",
|
||||
"post4",
|
||||
"post5",
|
||||
],
|
||||
"metadata": {
|
||||
"blogDescription": "Blog Description",
|
||||
"blogTitle": "Blog Title",
|
||||
"nextPage": undefined,
|
||||
"page": 1,
|
||||
"permalink": "/",
|
||||
"postsPerPage": 10,
|
||||
"previousPage": undefined,
|
||||
"totalCount": 5,
|
||||
"totalPages": 1,
|
||||
},
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`paginateBlogPosts generates pages 1`] = `
|
||||
[
|
||||
{
|
||||
"items": [
|
||||
|
@ -78,7 +103,7 @@ exports[`paginateBlogPosts generates right pages 1`] = `
|
|||
]
|
||||
`;
|
||||
|
||||
exports[`paginateBlogPosts generates right pages 2`] = `
|
||||
exports[`paginateBlogPosts generates pages at blog root 1`] = `
|
||||
[
|
||||
{
|
||||
"items": [
|
||||
|
@ -133,26 +158,56 @@ exports[`paginateBlogPosts generates right pages 2`] = `
|
|||
]
|
||||
`;
|
||||
|
||||
exports[`paginateBlogPosts generates right pages 3`] = `
|
||||
exports[`paginateBlogPosts generates pages with custom pageBasePath 1`] = `
|
||||
[
|
||||
{
|
||||
"items": [
|
||||
"post1",
|
||||
"post2",
|
||||
],
|
||||
"metadata": {
|
||||
"blogDescription": "Blog Description",
|
||||
"blogTitle": "Blog Title",
|
||||
"nextPage": "/blog/customPageBasePath/2",
|
||||
"page": 1,
|
||||
"permalink": "/blog",
|
||||
"postsPerPage": 2,
|
||||
"previousPage": undefined,
|
||||
"totalCount": 5,
|
||||
"totalPages": 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
"items": [
|
||||
"post3",
|
||||
"post4",
|
||||
],
|
||||
"metadata": {
|
||||
"blogDescription": "Blog Description",
|
||||
"blogTitle": "Blog Title",
|
||||
"nextPage": "/blog/customPageBasePath/3",
|
||||
"page": 2,
|
||||
"permalink": "/blog/customPageBasePath/2",
|
||||
"postsPerPage": 2,
|
||||
"previousPage": "/blog",
|
||||
"totalCount": 5,
|
||||
"totalPages": 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
"items": [
|
||||
"post5",
|
||||
],
|
||||
"metadata": {
|
||||
"blogDescription": "Blog Description",
|
||||
"blogTitle": "Blog Title",
|
||||
"nextPage": undefined,
|
||||
"page": 1,
|
||||
"permalink": "/",
|
||||
"postsPerPage": 10,
|
||||
"previousPage": undefined,
|
||||
"page": 3,
|
||||
"permalink": "/blog/customPageBasePath/3",
|
||||
"postsPerPage": 2,
|
||||
"previousPage": "/blog/customPageBasePath/2",
|
||||
"totalCount": 5,
|
||||
"totalPages": 1,
|
||||
"totalPages": 3,
|
||||
},
|
||||
},
|
||||
]
|
||||
|
|
|
@ -38,14 +38,15 @@ describe('truncate', () => {
|
|||
});
|
||||
|
||||
describe('paginateBlogPosts', () => {
|
||||
it('generates right pages', () => {
|
||||
const blogPosts = [
|
||||
{id: 'post1', metadata: {}, content: 'Foo 1'},
|
||||
{id: 'post2', metadata: {}, content: 'Foo 2'},
|
||||
{id: 'post3', metadata: {}, content: 'Foo 3'},
|
||||
{id: 'post4', metadata: {}, content: 'Foo 4'},
|
||||
{id: 'post5', metadata: {}, content: 'Foo 5'},
|
||||
] as BlogPost[];
|
||||
const blogPosts = [
|
||||
{id: 'post1', metadata: {}, content: 'Foo 1'},
|
||||
{id: 'post2', metadata: {}, content: 'Foo 2'},
|
||||
{id: 'post3', metadata: {}, content: 'Foo 3'},
|
||||
{id: 'post4', metadata: {}, content: 'Foo 4'},
|
||||
{id: 'post5', metadata: {}, content: 'Foo 5'},
|
||||
] as BlogPost[];
|
||||
|
||||
it('generates pages', () => {
|
||||
expect(
|
||||
paginateBlogPosts({
|
||||
blogPosts,
|
||||
|
@ -53,8 +54,12 @@ describe('paginateBlogPosts', () => {
|
|||
blogTitle: 'Blog Title',
|
||||
blogDescription: 'Blog Description',
|
||||
postsPerPageOption: 2,
|
||||
pageBasePath: 'page',
|
||||
}),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('generates pages at blog root', () => {
|
||||
expect(
|
||||
paginateBlogPosts({
|
||||
blogPosts,
|
||||
|
@ -62,8 +67,12 @@ describe('paginateBlogPosts', () => {
|
|||
blogTitle: 'Blog Title',
|
||||
blogDescription: 'Blog Description',
|
||||
postsPerPageOption: 2,
|
||||
pageBasePath: 'page',
|
||||
}),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('generates a single page', () => {
|
||||
expect(
|
||||
paginateBlogPosts({
|
||||
blogPosts,
|
||||
|
@ -71,6 +80,20 @@ describe('paginateBlogPosts', () => {
|
|||
blogTitle: 'Blog Title',
|
||||
blogDescription: 'Blog Description',
|
||||
postsPerPageOption: 10,
|
||||
pageBasePath: 'page',
|
||||
}),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('generates pages with custom pageBasePath', () => {
|
||||
expect(
|
||||
paginateBlogPosts({
|
||||
blogPosts,
|
||||
basePageUrl: '/blog',
|
||||
blogTitle: 'Blog Title',
|
||||
blogDescription: 'Blog Description',
|
||||
postsPerPageOption: 2,
|
||||
pageBasePath: 'customPageBasePath',
|
||||
}),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
|
|
@ -57,12 +57,14 @@ export function paginateBlogPosts({
|
|||
blogTitle,
|
||||
blogDescription,
|
||||
postsPerPageOption,
|
||||
pageBasePath,
|
||||
}: {
|
||||
blogPosts: BlogPost[];
|
||||
basePageUrl: string;
|
||||
blogTitle: string;
|
||||
blogDescription: string;
|
||||
postsPerPageOption: number | 'ALL';
|
||||
pageBasePath: string;
|
||||
}): BlogPaginated[] {
|
||||
const totalCount = blogPosts.length;
|
||||
const postsPerPage =
|
||||
|
@ -73,7 +75,7 @@ export function paginateBlogPosts({
|
|||
|
||||
function permalink(page: number) {
|
||||
return page > 0
|
||||
? normalizeUrl([basePageUrl, `page/${page + 1}`])
|
||||
? normalizeUrl([basePageUrl, pageBasePath, `${page + 1}`])
|
||||
: basePageUrl;
|
||||
}
|
||||
|
||||
|
@ -111,6 +113,7 @@ export function getBlogTags({
|
|||
blogTitle: string;
|
||||
blogDescription: string;
|
||||
postsPerPageOption: number | 'ALL';
|
||||
pageBasePath: string;
|
||||
}): BlogTags {
|
||||
const groups = groupTaggedItems(
|
||||
blogPosts,
|
||||
|
|
|
@ -107,6 +107,7 @@ export default async function pluginContentBlog(
|
|||
blogDescription,
|
||||
blogTitle,
|
||||
blogSidebarTitle,
|
||||
pageBasePath,
|
||||
} = options;
|
||||
|
||||
const baseBlogUrl = normalizeUrl([baseUrl, routeBasePath]);
|
||||
|
@ -121,11 +122,10 @@ export default async function pluginContentBlog(
|
|||
blogListPaginated: [],
|
||||
blogTags: {},
|
||||
blogTagsListPath,
|
||||
blogTagsPaginated: [],
|
||||
};
|
||||
}
|
||||
|
||||
// Colocate next and prev metadata.
|
||||
// Collocate next and prev metadata.
|
||||
listedBlogPosts.forEach((blogPost, index) => {
|
||||
const prevItem = index > 0 ? listedBlogPosts[index - 1] : null;
|
||||
if (prevItem) {
|
||||
|
@ -153,6 +153,7 @@ export default async function pluginContentBlog(
|
|||
blogDescription,
|
||||
postsPerPageOption,
|
||||
basePageUrl: baseBlogUrl,
|
||||
pageBasePath,
|
||||
});
|
||||
|
||||
const blogTags: BlogTags = getBlogTags({
|
||||
|
@ -160,6 +161,7 @@ export default async function pluginContentBlog(
|
|||
postsPerPageOption,
|
||||
blogDescription,
|
||||
blogTitle,
|
||||
pageBasePath,
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
|
@ -45,6 +45,7 @@ export const DEFAULT_OPTIONS: PluginOptions = {
|
|||
routeBasePath: 'blog',
|
||||
tagsBasePath: 'tags',
|
||||
archiveBasePath: 'archive',
|
||||
pageBasePath: 'page',
|
||||
path: 'blog',
|
||||
editLocalizedFiles: false,
|
||||
authorsMapPath: 'authors.yml',
|
||||
|
@ -59,6 +60,7 @@ const PluginOptionSchema = Joi.object<PluginOptions>({
|
|||
.allow(null),
|
||||
routeBasePath: RouteBasePathSchema.default(DEFAULT_OPTIONS.routeBasePath),
|
||||
tagsBasePath: Joi.string().default(DEFAULT_OPTIONS.tagsBasePath),
|
||||
pageBasePath: Joi.string().default(DEFAULT_OPTIONS.pageBasePath),
|
||||
include: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.include),
|
||||
exclude: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.exclude),
|
||||
postsPerPage: Joi.alternatives()
|
||||
|
|
|
@ -351,9 +351,14 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
|||
routeBasePath: string;
|
||||
/**
|
||||
* URL route for the tags section of your blog. Will be appended to
|
||||
* `routeBasePath`. **DO NOT** include a trailing slash.
|
||||
* `routeBasePath`.
|
||||
*/
|
||||
tagsBasePath: string;
|
||||
/**
|
||||
* URL route for the pages section of your blog. Will be appended to
|
||||
* `routeBasePath`.
|
||||
*/
|
||||
pageBasePath: string;
|
||||
/**
|
||||
* URL route for the archive section of your blog. Will be appended to
|
||||
* `routeBasePath`. **DO NOT** include a trailing slash. Use `null` to
|
||||
|
|
|
@ -53,6 +53,7 @@ The component used for Markdown pages is `@theme/MDXPage`. React pages are direc
|
|||
The blog creates the following routes:
|
||||
|
||||
- **Posts list pages**: `/`, `/page/2`, `/page/3`...
|
||||
- The route is customizable through the `pageBasePath` option.
|
||||
- The component is `@theme/BlogListPage`.
|
||||
- **Post pages**: `/2021/11/21/algolia-docsearch-migration`, `/2021/05/12/announcing-docusaurus-two-beta`...
|
||||
- Generated from each Markdown post.
|
||||
|
|
|
@ -47,7 +47,8 @@ Accepted fields:
|
|||
| `blogSidebarCount` | <code>number \| 'ALL'</code> | `5` | Number of blog post elements to show in the blog sidebar. `'ALL'` to show all blog posts; `0` to disable. |
|
||||
| `blogSidebarTitle` | `string` | `'Recent posts'` | Title of the blog sidebar. |
|
||||
| `routeBasePath` | `string` | `'blog'` | URL route for the blog section of your site. **DO NOT** include a trailing slash. Use `/` to put the blog at root path. |
|
||||
| `tagsBasePath` | `string` | `'tags'` | URL route for the tags section of your blog. Will be appended to `routeBasePath`. **DO NOT** include a trailing slash. |
|
||||
| `tagsBasePath` | `string` | `'tags'` | URL route for the tags section of your blog. Will be appended to `routeBasePath`. |
|
||||
| `pageBasePath` | `string` | `'page'` | URL route for the pages section of your blog. Will be appended to `routeBasePath`. |
|
||||
| `archiveBasePath` | <code>string \| null</code> | `'archive'` | URL route for the archive section of your blog. Will be appended to `routeBasePath`. **DO NOT** include a trailing slash. Use `null` to disable generation of archive. |
|
||||
| `include` | `string[]` | `['**/*.{md,mdx}']` | Array of glob patterns matching Markdown files to be built, relative to the content path. |
|
||||
| `exclude` | `string[]` | _See example configuration_ | Array of glob patterns matching Markdown files to be excluded. Serves as refinement based on the `include` option. |
|
||||
|
|
Loading…
Add table
Reference in a new issue