126 lines
2.9 KiB
JavaScript
126 lines
2.9 KiB
JavaScript
|
/**
|
||
|
* Implement Gatsby's Node APIs in this file.
|
||
|
*
|
||
|
* See: https://www.gatsbyjs.com/docs/reference/config-files/gatsby-node/
|
||
|
*/
|
||
|
|
||
|
const path = require(`path`)
|
||
|
const { createFilePath } = require(`gatsby-source-filesystem`)
|
||
|
|
||
|
// Define the template for blog post
|
||
|
const blogPost = path.resolve(`./src/templates/blog-post.js`)
|
||
|
|
||
|
/**
|
||
|
* @type {import('gatsby').GatsbyNode['createPages']}
|
||
|
*/
|
||
|
exports.createPages = async ({ graphql, actions, reporter }) => {
|
||
|
const { createPage } = actions
|
||
|
|
||
|
// Get all markdown blog posts sorted by date
|
||
|
const result = await graphql(`
|
||
|
{
|
||
|
allMarkdownRemark(sort: { frontmatter: { date: ASC } }, limit: 1000) {
|
||
|
nodes {
|
||
|
id
|
||
|
fields {
|
||
|
slug
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
`)
|
||
|
|
||
|
if (result.errors) {
|
||
|
reporter.panicOnBuild(
|
||
|
`There was an error loading your blog posts`,
|
||
|
result.errors
|
||
|
)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
const posts = result.data.allMarkdownRemark.nodes
|
||
|
|
||
|
// Create blog posts pages
|
||
|
// But only if there's at least one markdown file found at "content/blog" (defined in gatsby-config.js)
|
||
|
// `context` is available in the template as a prop and as a variable in GraphQL
|
||
|
|
||
|
if (posts.length > 0) {
|
||
|
posts.forEach((post, index) => {
|
||
|
const previousPostId = index === 0 ? null : posts[index - 1].id
|
||
|
const nextPostId = index === posts.length - 1 ? null : posts[index + 1].id
|
||
|
|
||
|
createPage({
|
||
|
path: post.fields.slug,
|
||
|
component: blogPost,
|
||
|
context: {
|
||
|
id: post.id,
|
||
|
previousPostId,
|
||
|
nextPostId,
|
||
|
},
|
||
|
})
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @type {import('gatsby').GatsbyNode['onCreateNode']}
|
||
|
*/
|
||
|
exports.onCreateNode = ({ node, actions, getNode }) => {
|
||
|
const { createNodeField } = actions
|
||
|
|
||
|
if (node.internal.type === `MarkdownRemark`) {
|
||
|
const value = createFilePath({ node, getNode })
|
||
|
|
||
|
createNodeField({
|
||
|
name: `slug`,
|
||
|
node,
|
||
|
value,
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @type {import('gatsby').GatsbyNode['createSchemaCustomization']}
|
||
|
*/
|
||
|
exports.createSchemaCustomization = ({ actions }) => {
|
||
|
const { createTypes } = actions
|
||
|
|
||
|
// Explicitly define the siteMetadata {} object
|
||
|
// This way those will always be defined even if removed from gatsby-config.js
|
||
|
|
||
|
// Also explicitly define the Markdown frontmatter
|
||
|
// This way the "MarkdownRemark" queries will return `null` even when no
|
||
|
// blog posts are stored inside "content/blog" instead of returning an error
|
||
|
createTypes(`
|
||
|
type SiteSiteMetadata {
|
||
|
author: Author
|
||
|
siteUrl: String
|
||
|
social: Social
|
||
|
}
|
||
|
|
||
|
type Author {
|
||
|
name: String
|
||
|
summary: String
|
||
|
}
|
||
|
|
||
|
type Social {
|
||
|
twitter: String
|
||
|
}
|
||
|
|
||
|
type MarkdownRemark implements Node {
|
||
|
frontmatter: Frontmatter
|
||
|
fields: Fields
|
||
|
}
|
||
|
|
||
|
type Frontmatter {
|
||
|
title: String
|
||
|
description: String
|
||
|
date: Date @dateformat
|
||
|
}
|
||
|
|
||
|
type Fields {
|
||
|
slug: String
|
||
|
}
|
||
|
`)
|
||
|
}
|