Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const path = require('path');
- const { createFilePath } = require('gatsby-source-filesystem');
- const {
- getPathnameForMdxNode,
- getContentByCategory,
- } = require('./build-helpers/gatsby-node.helpers');
- const LEGACY_POST_SLUGS = [
- 'animating-the-unanimatable',
- 'dynamic-bezier-curves',
- 'effective-collaboration',
- 'folding-the-dom',
- 'rainbow-button',
- 'remote-work',
- 'remote-work-2',
- ];
- const createPaginatedPage = ({
- content,
- rootPath,
- component,
- createPage,
- context = {},
- }) => {
- // Pagination!
- const numPages = Math.ceil(content.length / PAGE_SIZE);
- Array.from({ length: numPages }).forEach((_, page) => {
- let pathname = rootPath;
- if (page > 0) {
- pathname = `${pathname}/${page + 1}`;
- }
- createPage({
- path: pathname,
- component,
- context: {
- limit: PAGE_SIZE,
- skip: page * PAGE_SIZE,
- numPages,
- currentPage: page + 1,
- ...context,
- },
- });
- });
- };
- /**
- * Many pages are created programmatically, including:
- * - Articles and tutorials themselves
- * - The "latest" page ('/latest', chronologically sorted list of all content)
- * - Category pages (eg. '/tutorials/react', including pagination)
- * - Root "tutorials" page ('/tutorials', shows top content from each
- * category)
- *
- * This is done so that I can have complete control over the pathnames (plus
- * you kinda have to do it this way for pagination).
- *
- * Also, I need to create redirects for all my legacy posts, so that links
- * don't break.
- */
- exports.createPages = async function({ actions, graphql }) {
- const { createPage, createRedirect } = actions;
- const { data } = await graphql(`
- query {
- allMdx(
- sort: { fields: [frontmatter___publishedOn], order: DESC }
- limit: 1000
- ) {
- edges {
- node {
- id
- fields {
- slug
- }
- frontmatter {
- title
- isPublished
- publishedOn
- type
- abstract
- level
- categories
- interactive
- alwaysShowDate
- }
- }
- }
- }
- }
- `);
- // Create individual pages, one for each category.
- const content = data.allMdx.edges.map(edge => edge.node);
- content.forEach(item => {
- const { slug } = item.fields;
- const { categories } = item.frontmatter;
- const firstCategory = categories[0];
- categories.forEach(category => {
- const pathname = getPathnameForMdxNode(category, slug);
- const componentPath =
- item.frontmatter.type === 'tutorial'
- ? './src/components/TemplateTutorial/TemplateTutorial.js'
- : './src/components/TemplateArticle/TemplateArticle.js';
- createPage({
- path: pathname,
- component: path.resolve(componentPath),
- context: {
- id: item.id,
- category,
- canonicalCategory: firstCategory,
- },
- });
- });
- // If this is a legacy post, create a redirect at the old URL (/posts/:slug)
- const isLegacy = LEGACY_POST_SLUGS.includes(slug);
- if (isLegacy) {
- const [primaryCategory] = categories;
- const pathname = getPathnameForMdxNode(primaryCategory, slug);
- createRedirect({
- fromPath: `/posts/${slug}`,
- isPermanent: true,
- redirectInBrowser: true, // TODO: try false?
- toPath: '/' + pathname,
- });
- }
- });
- // Create the `/latest` page:
- // ALL CONTENT
- //
- // FUTURE: If I get >25 articles, should paginate this:
- // createPaginatedPage({
- // content,
- // rootPath: '/latest',
- // component: path.resolve(
- // './src/components/TemplateLatest/TemplateLatest.js'
- // ),
- // createPage,
- // });
- //
- createPage({
- path: '/latest',
- component: path.resolve(
- './src/components/TemplateLatest/TemplateLatest.js'
- ),
- context: {
- limit: 1000,
- skip: 0,
- },
- });
- // Create the root '/tutorials' page:
- // (Tutorials and articles grouped by category)
- createPaginatedPage({
- content,
- rootPath: '/tutorials',
- component: path.resolve(
- './src/components/TemplateContentGrouped/TemplateContentGrouped.js'
- ),
- createPage,
- });
- const contentByCategory = getContentByCategory(content);
- // Create all the category pages
- // /category/:category
- Object.entries(contentByCategory).forEach(([category, childContent]) => {
- // Pagination!
- let rootPath = `/tutorials/${category}`;
- createPaginatedPage({
- content: childContent,
- rootPath,
- component: path.resolve(
- './src/components/TemplateCategoryList/TemplateCategoryList.js'
- ),
- createPage,
- context: {
- category,
- },
- });
- });
- };
- exports.onCreateNode = ({ node, actions, getNode }) => {
- const { createNodeField } = actions;
- if (node.internal.type === `Mdx`) {
- // If we've manually specified a slug, use that.
- // Otherwise, generate one from the file path.
- const slug =
- node.frontmatter.slug ||
- createFilePath({ node, getNode })
- .replace(/^\//, '')
- .replace(/\/$/, '');
- createNodeField({
- name: `slug`,
- node,
- value: slug,
- });
- createNodeField({
- name: `pathname`,
- node,
- value: '/' + getPathnameForMdxNode(node.frontmatter.categories[0], slug),
- });
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement