-
Notifications
You must be signed in to change notification settings - Fork 0
/
gatsby-node.js
executable file
Β·177 lines (154 loc) Β· 5.81 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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
const path = require('path')
const locales = require('./config/i18n')
const {
localizedSlug,
findKey,
removeTrailingSlash
} = require('./src/utils/gatsby-node-helpers')
// Refactor Gatsby Queries: https://github.com/gatsbyjs/gatsby/issues/1634
exports.onCreatePage = ({ page, actions }) => {
const { createPage, deletePage } = actions
// First delete the incoming page that was automatically created by Gatsby
// So everything in src/pages/
deletePage(page)
// Grab the keys ('en' & 'pt') of locales and map over them
Object.keys(locales).map(lang => {
// Use the values defined in "locales" to construct the path
const localizedPath = locales[lang].default
? page.path
: `${locales[lang].path}${page.path}`
return createPage({
// Pass on everything from the original page
...page,
// Since page.path returns with a trailing slash (e.g. "/pt/")
// We want to remove that (e.g. "pt/")
path: removeTrailingSlash(localizedPath),
// Pass in the locale as context to every page
// This context also gets passed to the src/components/layout file
// This should ensure that the locale is available on every page
context: {
...page.context,
locale: lang,
dateFormat: locales[lang].dateFormat
}
})
})
}
// Correcting language and slug to the frontmatter of each file
// A new node is created automatically with the filename
// It's necessary to do that to filter by language
// And the slug make sure the urls will be the same for all posts
exports.onCreateNode = ({ node, actions }) => {
const { createNodeField } = actions
// Check for "MarkdownRemark" type so that other files (e.g. images) are exluded
if (node.internal.type === 'MarkdownRemark') {
// Use path.basename
// https://nodejs.org/api/path.html#path_path_basename_path_ext
// It will return the file name without '.md' string (e.g. "file-name" or "file-name.lang")
const name = path.basename(node.fileAbsolutePath, '.md')
// Find the key that has "default: true" set (in this case it returns "en")
const defaultKey = findKey(locales, o => o.default === true)
// Check if file.name.lang has the default lang type.
// (in this case the default language is for files set with "en")
const isDefault = name.split('.')[1] === defaultKey
// Files are defined with "name-with-dashes.lang.md"
// So grab the lang from that string
// If it's the default language, pass the locale for that
const lang = isDefault ? defaultKey : name.split('.')[1]
// Get the entire file name and remove the lang of it
const slugFileName = name.split('.')[0]
// Than remove the date if the name has the date info
const slug = slugFileName
const sectionRaw = path
.dirname(node.fileAbsolutePath)
.split(path.sep)
.pop()
const section = sectionRaw.charAt(0).toUpperCase() + sectionRaw.substring(1)
// Adding the nodes on GraphQL for each post as "fields"
createNodeField({ node, name: 'slug', value: slug })
createNodeField({ node, name: 'locale', value: lang })
createNodeField({ node, name: 'isDefault', value: isDefault })
createNodeField({ node, name: 'section', value: section })
}
}
// Creating Posts and Pages for each node in AllMarkdownRemark
exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions
// Templates for Posts List and Single post
const sectionItemTemplate = path.resolve('./src/templates/sectionItem.js')
const pageTemplate = path.resolve('./src/templates/page.js')
const miscTemplate = path.resolve('./src/templates/misc.js')
const result = await graphql(`
{
files: allMarkdownRemark(
sort: { fields: [frontmatter___date], order: DESC }
) {
edges {
node {
fields {
locale
isDefault
slug
}
frontmatter {
title
page
section
misc
}
parent {
... on File {
base
sourceInstanceName
}
}
}
}
}
}
`)
if (result.errors) {
console.error(result.errors)
return
}
// Posts and Pages created by markdown (from blog and pages directory)
const contentMarkdown = result.data.files.edges
// Creating each post
contentMarkdown.forEach(({ node: file }) => {
// Getting Slug and Title
const slug = file.fields.slug
// const title = file.frontmatter.title.toLowerCase()
const title = file.frontmatter.title
let section = false
// Use the fields created in exports.onCreateNode
const locale = file.fields.locale
const isDefault = file.fields.isDefault
// Check if it's page (to differentiate post and page)
const isPage = file.frontmatter.page
const isSection = file.frontmatter.section
const isMisc = file.frontmatter.misc
if (isSection) {
section = file.parent.sourceInstanceName.toLowerCase()
}
// Setting a template for page or post depending on the content
// let template = isPage ? pageTemplate : null
const template = isPage ? pageTemplate : isSection ? sectionItemTemplate : isMisc ? miscTemplate : null
// if (isSection) {
// template = sectionItemTemplate
// }
// if (isMisc) {
// template = miscTemplate
// }
template !== null && createPage({
path: localizedSlug({ isDefault, locale, slug, isPage, section }),
component: template,
context: {
// Pass both the "title" and "locale" to find a unique file
// Only the title would not have been sufficient as articles could have the same title
// in different languages, e.g. because an english phrase is also common in german
locale,
title
}
})
})
}