const path = require('path')
const _ = require('lodash')
const PAGINATION_OFFSET = 7
const createPosts = (createPage, createRedirect, edges) => {
edges.forEach(({ node }, i) => {
const prev = i === 0 ? null : edges[i - 1].node
const next = i === edges.length - 1 ? null : edges[i + 1].node
const pagePath = node.fields.slug
if (node.fields.redirects) {
node.fields.redirects.forEach(fromPath => {
createRedirect({
fromPath,
toPath: pagePath,
redirectInBrowser: true,
isPermanent: true,
})
})
}
createPage({
path: pagePath,
component: path.resolve(`./src/templates/post.js`),
context: {
id: node.id,
prev,
next,
},
})
})
}
exports.createPages = ({ actions, graphql }) =>
graphql(`
query {
allMdx(
filter: { frontmatter: { published: { ne: false } } }
sort: { order: DESC, fields: [frontmatter___date] }
) {
edges {
node {
id
parent {
... on File {
name
sourceInstanceName
}
}
excerpt(pruneLength: 250)
fields {
title
slug
date
}
}
}
}
}
`).then(({ data, errors }) => {
if (errors) {
return Promise.reject(errors)
}
if (_.isEmpty(data.allMdx)) {
return Promise.reject('There are no posts!')
}
const { edges } = data.allMdx
const { createRedirect, createPage } = actions
createPosts(createPage, createRedirect, edges)
createPaginatedPages(actions.createPage, edges, '/blog', {
categories: [],
})
})
exports.onCreateWebpackConfig = ({ actions }) => {
actions.setWebpackConfig({
resolve: {
modules: [path.resolve(__dirname, 'src'), 'node_modules'],
alias: {
'react-dom': '@hot-loader/react-dom',
$components: path.resolve(__dirname, 'src/components'),
},
},
})
}
const createPaginatedPages = (createPage, edges, pathPrefix, context) => {
const pages = edges.reduce((acc, value, index) => {
const pageIndex = Math.floor(index / PAGINATION_OFFSET)
if (!acc[pageIndex]) {
acc[pageIndex] = []
}
acc[pageIndex].push(value.node.id)
return acc
}, [])
pages.forEach((page, index) => {
const previousPagePath = `${pathPrefix}/${index + 1}`
const nextPagePath = index === 1 ? pathPrefix : `${pathPrefix}/${index - 1}`
createPage({
path: index > 0 ? `${pathPrefix}/${index}` : `${pathPrefix}`,
component: path.resolve(`src/templates/blog.js`),
context: {
pagination: {
page,
nextPagePath: index === 0 ? null : nextPagePath,
previousPagePath:
index === pages.length - 1 ? null : previousPagePath,
pageCount: pages.length,
pathPrefix,
},
...context,
},
})
})
}
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions
if (node.internal.type === `Mdx`) {
const parent = getNode(node.parent)
const titleSlugged = _.join(_.drop(parent.name.split('-'), 3), '-')
const slug =
parent.sourceInstanceName === 'legacy'
? `blog/${node.frontmatter.date
.split('T')[0]
.replace(/-/g, '/')}/${titleSlugged}`
: node.frontmatter.slug || titleSlugged
createNodeField({
name: 'id',
node,
value: node.id,
})
createNodeField({
name: 'published',
node,
value: node.frontmatter.published,
})
createNodeField({
name: 'title',
node,
value: node.frontmatter.title,
})
createNodeField({
name: 'description',
node,
value: node.frontmatter.description,
})
createNodeField({
name: 'slug',
node,
value: slug,
})
createNodeField({
name: 'date',
node,
value: node.frontmatter.date ? node.frontmatter.date.split(' ')[0] : '',
})
createNodeField({
name: 'banner',
node,
value: node.frontmatter.banner,
})
createNodeField({
name: 'categories',
node,
value: node.frontmatter.categories || [],
})
createNodeField({
name: 'keywords',
node,
value: node.frontmatter.keywords || [],
})
createNodeField({
name: 'redirects',
node,
value: node.frontmatter.redirects,
})
createNodeField({
name: 'isPost',
node,
value: true,
})
}
}