website/gatsby-node.js

122 lines
3.0 KiB
JavaScript
Raw Normal View History

2020-11-28 03:35:36 +00:00
/* eslint-env node */
2020-11-28 00:39:21 +00:00
const path = require('path');
2020-11-27 16:08:32 +00:00
2020-11-28 03:35:36 +00:00
/**
* Generates a set of pages that are blog-like, where there should be an
* "landing page" that needs to be paginated followed by individual items.
*
* This function does two essential features:
* 1. renders individual pages
* 2. renders index pages with context needed for pagination
*
* @param {function} createPage Gatsby createPage function
* @param {function} graphql Gatsby graphql function
* @param {object} reporter Gatbsy reporter object
* @param {string} queryAbsolutePathGlob The source code glob to find the pages
* for rendering
* @param {string} siteRootPath The public root path to generate the pages under
* @param {string} indexFilePath The source code path to the index template file
* @param {string} itemFilePath The source code path to the item template file
*/
async function generatePages(
createPage,
graphql,
reporter,
queryAbsolutePathGlob,
siteRootPath,
indexFilePath,
itemFilePath
) {
2020-11-27 19:07:44 +00:00
const result = await graphql(`
{
allMdx(
2020-11-28 03:35:36 +00:00
filter: { fileAbsolutePath: { glob: "${queryAbsolutePathGlob}" } }
2020-11-27 19:07:44 +00:00
) {
edges {
node {
frontmatter {
path
2020-11-27 20:25:22 +00:00
hidden
2020-11-27 19:07:44 +00:00
}
id
2020-11-27 16:08:32 +00:00
}
}
}
}
2020-11-27 19:07:44 +00:00
`);
2020-11-27 16:08:32 +00:00
if (result.errors) {
reporter.panicOnBuild(`Error while running GraphQL query.`);
return;
}
2020-11-28 00:39:21 +00:00
const posts = result.data.allMdx.edges.filter(
({ node }) => !node.frontmatter.hidden
);
2020-11-27 19:19:33 +00:00
const postsPerPage = 10;
2020-11-27 19:07:44 +00:00
const numPages = Math.ceil(posts.length / postsPerPage);
Array.from({ length: numPages }).forEach((_, i) => {
createPage({
2020-11-28 03:35:36 +00:00
path: siteRootPath + (i === 0 ? '' : `/${i + 1}`),
component: path.resolve(indexFilePath),
2020-11-27 19:07:44 +00:00
context: {
limit: postsPerPage,
skip: i * postsPerPage,
numPages,
currentPage: i + 1,
2020-11-28 03:35:36 +00:00
rootPath: siteRootPath,
2020-11-27 19:07:44 +00:00
},
2020-11-28 00:39:21 +00:00
});
2020-11-27 19:07:44 +00:00
});
2020-11-27 20:25:22 +00:00
// Must decouple to ensure hidden pages are still rendered, just excluded from
// notes mapping
result.data.allMdx.edges.forEach(({ node }) => {
2020-11-27 16:08:32 +00:00
createPage({
2020-11-28 03:35:36 +00:00
path: `${siteRootPath}/${node.frontmatter.path}`,
component: path.resolve(itemFilePath),
2020-11-27 16:08:32 +00:00
context: {
id: node.id,
2020-11-27 19:07:44 +00:00
},
2020-11-27 16:08:32 +00:00
});
});
2020-11-28 03:35:36 +00:00
}
exports.createPages = async ({ actions, graphql, reporter }) => {
const { createPage } = actions;
await generatePages(
createPage,
graphql,
reporter,
'**/src/notes/*',
'/notes',
'./src/templates/notes.tsx',
2020-11-28 20:50:20 +00:00
'./src/templates/note.tsx',
2020-11-28 03:35:36 +00:00
);
await generatePages(
createPage,
graphql,
reporter,
'**/src/projects/*',
'/projects',
'./src/templates/projects.tsx',
2020-11-28 20:50:20 +00:00
'./src/templates/project.tsx',
2020-11-28 03:35:36 +00:00
);
2020-11-28 00:39:21 +00:00
};
2020-11-28 03:35:36 +00:00
2020-11-27 20:25:22 +00:00
exports.createSchemaCustomization = ({ actions: { createTypes } }) => {
createTypes(`
type Mdx implements Node {
2020-11-28 05:07:26 +00:00
frontmatter: CommonFrontmatter
2020-11-27 20:25:22 +00:00
}
2020-11-28 05:07:26 +00:00
type CommonFrontmatter {
hidden: Boolean,
lang: String,
2020-11-28 20:50:20 +00:00
tags: [String],
subtitle: String,
2020-11-27 20:25:22 +00:00
}
`);
};