/* eslint-env node */ const path = require('path'); /** * 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 ) { const result = await graphql(` { allMdx( filter: { fileAbsolutePath: { glob: "${queryAbsolutePathGlob}" } } ) { edges { node { frontmatter { path hidden } id } } } } `); if (result.errors) { reporter.panicOnBuild(`Error while running GraphQL query.`); return; } const posts = result.data.allMdx.edges.filter( ({ node }) => !node.frontmatter.hidden ); const postsPerPage = 10; const numPages = Math.ceil(posts.length / postsPerPage); Array.from({ length: numPages }).forEach((_, i) => { createPage({ path: siteRootPath + (i === 0 ? '' : `/${i + 1}`), component: path.resolve(indexFilePath), context: { limit: postsPerPage, skip: i * postsPerPage, numPages, currentPage: i + 1, rootPath: siteRootPath, }, }); }); // Must decouple to ensure hidden pages are still rendered, just excluded from // notes mapping result.data.allMdx.edges.forEach(({ node }) => { createPage({ path: `${siteRootPath}/${node.frontmatter.path}`, component: path.resolve(itemFilePath), context: { id: node.id, }, }); }); } exports.createPages = async ({ actions, graphql, reporter }) => { const { createPage } = actions; await generatePages( createPage, graphql, reporter, '**/src/notes/*', '/notes', './src/templates/notes.tsx', './src/templates/note.tsx', ); await generatePages( createPage, graphql, reporter, '**/src/projects/*', '/projects', './src/templates/projects.tsx', './src/templates/project.tsx', ); }; exports.createSchemaCustomization = ({ actions: { createTypes } }) => { createTypes(` type Mdx implements Node { frontmatter: CommonFrontmatter } type CommonFrontmatter { hidden: Boolean, lang: String, tags: [String], subtitle: String, } `); };