-
Notifications
You must be signed in to change notification settings - Fork 0
/
gatsby-node.js
120 lines (108 loc) · 2.98 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
const path = require('path');
const slash = require('slash');
const {kebabCase, uniq, get, compact, times} = require('lodash');
// Don't forget to update hard code values into:
// - `templates/blog-page.tsx:23`
// - `pages/blog.tsx:26`
// - `pages/blog.tsx:121`
const POSTS_PER_PAGE = 10;
const cleanArray = arr => compact(uniq(arr));
// Create slugs for files.
// Slug will used for blog page path.
exports.onCreateNode = ({node, actions, getNode}) => {
const {createNodeField} = actions;
let slug;
switch (node.internal.type) {
case 'MarkdownRemark':
const fileNode = getNode(node.parent);
const [basePath, name] = fileNode.relativePath.split('/');
slug = `/${basePath}/${name}/`;
break;
}
if (slug) {
createNodeField({node, name: 'slug', value: slug});
}
};
// Fixes cannot find fs errors
exports.onCreateWebpackConfig = ({actions}) => {
actions.setWebpackConfig({
node: {
fs: 'empty'
}
});
};
// Implement the Gatsby API `createPages`.
// This is called after the Gatsby bootstrap is finished
// so you have access to any information necessary to
// programatically create pages.
exports.createPages = ({graphql, actions}) => {
const {createPage} = actions;
return new Promise((resolve, reject) => {
const templates = ['blogPost', 'tagsPage', 'blogPage']
.reduce((mem, templateName) => {
return Object.assign({}, mem,
{[templateName]: path.resolve(`src/templates/${kebabCase(templateName)}.tsx`)});
}, {});
graphql(
`
{
posts: allMarkdownRemark {
edges {
node {
fields {
slug
}
frontmatter {
tags
}
}
}
}
}
`
).then(result => {
if (result.errors) {
return reject(result.errors);
}
const posts = result.data.posts.edges.map(p => p.node);
// Create blog pages
posts
.filter(post => post.fields.slug.startsWith('/blog/'))
.forEach(post => {
createPage({
path: post.fields.slug,
component: slash(templates.blogPost),
context: {
slug: post.fields.slug
}
});
});
// Create tags pages
posts
.reduce((mem, post) =>
cleanArray(mem.concat(get(post, 'frontmatter.tags')))
, [])
.forEach(tag => {
createPage({
path: `/blog/tags/${kebabCase(tag)}/`,
component: slash(templates.tagsPage),
context: {
tag
}
});
});
// Create blog pagination
const pageCount = Math.ceil(posts.length / POSTS_PER_PAGE);
times(pageCount, index => {
createPage({
path: `/blog/page/${index + 1}/`,
component: slash(templates.blogPage),
context: {
skip: index * POSTS_PER_PAGE
}
});
});
resolve();
});
});
};