-
Notifications
You must be signed in to change notification settings - Fork 1
/
gatsby-node.js
141 lines (128 loc) Β· 4.38 KB
/
gatsby-node.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
const path = require(`path`);
const { createFilePath } = require(`gatsby-source-filesystem`);
/**
* Our static content generator function.
*
* @param {object} o
*/
exports.createPages = async ({ graphql, actions, reporter }) => {
const { createPage } = actions;
// Get all posts by date
// TODO: for whatever reason, the filter is not working here; whatever, will come back to it later
const response = await graphql(
`
{
allMarkdownRemark(
sort: { frontmatter: { date: DESC } }
limit: 1000
filter: { frontmatter: { published: { eq: true } } }
) {
edges {
node {
fields {
slug
}
frontmatter {
title
type
published
}
}
}
}
}
`
);
// If an error occurs on fetch, crash
if (response.errors) {
reporter.panicOnBuild(`Error while running GraphQL query.`);
throw response.errors;
}
// Get data: post objects, number of posts to render within each template, the template itself to create pages
const posts = response.data.allMarkdownRemark.edges;
// Create blog content, design content, and project content
createPagesByType("blog", posts, createPage);
createPagesByType("design", posts, createPage);
createPagesByType("projects", posts, createPage);
createPagesByType("travel", posts, createPage);
};
/**
* Create pages of a certain type.
*
* @param {string} postType the post type (one-of: blog, design, projects)
* @param {Object[]} allPosts the array of all posts (i.e., really, Markdown files)
* @param {function} createPage a function to create a page; given by Gatsby
*/
const createPagesByType = (postType, allPosts, createPage) => {
// Get templates; define posts per page
const postsPerPage = 6;
const postTemplate = path.resolve(`./src/templates/PostTemplate.tsx`);
const postListTemplate = path.resolve(
`./src/templates/PostListTemplate.tsx`
);
// Filter allPosts to posts of specified type
const posts = allPosts.filter(post => filterPosts(post, postType));
// Compute number of pages
const numPages = Math.ceil(posts.length / postsPerPage);
// For each post, create page (i.e., postTemplate)
posts.forEach((post, i) => {
const previous = i === posts.length - 1 ? null : posts[i + 1].node;
const next = i === 0 ? null : posts[i - 1].node;
createPage({
path: `/${postType}${post.node.fields.slug}`,
component: postTemplate,
context: {
slug: post.node.fields.slug,
previous,
next,
},
});
});
// Create numPages pages with postsPerPage posts on each page (i.e., postListTemplate)
Array.from({ length: numPages }).forEach((_, i) => {
createPage({
path: i === 0 ? `/${postType}` : `/${postType}/${i + 1}`,
component: postListTemplate,
context: {
type: postType,
limit: postsPerPage,
skip: i * postsPerPage,
numPages: numPages,
currentPage: i + 1,
},
});
});
};
/**
* A helper function to filter posts down.
*
* @param {object} post the post itself
* @param {string} postType the type of the post
* @returns {boolean} whether or not the post's type matches postType
*/
const filterPosts = (post, postType) => {
return (
post.node.frontmatter.published === true &&
post.node.frontmatter.type === postType
);
};
/**
* Creates needed file paths and node fields.
*
* (This also enables RSS!)
*
* See more here {@link https://gatsbyjs.com/docs/reference/config-files/gatsby-node/#onCreateNode}
*
* @param {object} o
*/
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions;
if (node.internal.type === `MarkdownRemark`) {
const value = createFilePath({ node, getNode });
createNodeField({
name: `slug`,
node,
value,
});
}
};