@@ -5,7 +5,89 @@ const frontmatterParser = require("parser-front-matter")
5
5
const { readFile } = require ( "fs-extra" )
6
6
const { promisify } = require ( "util" )
7
7
8
+ exports . createSchemaCustomization = ( { actions, schema } ) => {
9
+ const gql = String . raw ;
10
+ const { createTypes } = actions ;
11
+
12
+ createTypes ( gql `
13
+ type BlogPost implements Node
14
+ @childOf(types: ["MarkdownRemark"])
15
+ {
16
+ postId: String!
17
+ title: String!
18
+ tags: [String!]!
19
+ date: Date! @dateformat(formatString: "YYYY-MM-DD")
20
+ authors: [String!]!
21
+ guestBio: String
22
+ remark: MarkdownRemark! @link # backlink to the parent
23
+ }
24
+ ` ) ;
25
+ } ;
26
+
27
+ // Transform nodes, each of logic inside here can be extracted to a separated plugin later.
28
+ exports . onCreateNode = async ( {
29
+ reporter,
30
+ node,
31
+ actions,
32
+ createNodeId,
33
+ createContentDigest,
34
+ } ) => {
35
+ const { createNode, createParentChildLink } = actions ;
36
+
37
+ // Derive content nodes from remark nodes
38
+ if ( node . internal . type === 'MarkdownRemark' ) {
39
+ if ( node . frontmatter . layout === 'blog' ) {
40
+ const nodeId = createNodeId ( `${ node . id } >>> BlogPost` ) ;
41
+
42
+ const permalink = node . frontmatter . permalink ;
43
+ if ( ! permalink ?. startsWith ( '/blog/' ) ) {
44
+ reporter . panicOnBuild ( `${ permalink } is not valid permalink for blog post` ) ;
45
+ return ;
46
+ }
47
+
48
+ // It contains a kind of transform logic. However, those logics can be extracted to resolvers into ahead of sourcing (createTypes)
49
+ const blogPostContent = {
50
+ id : nodeId ,
51
+ postId : permalink . replace ( '/blog/' , '' ) . replace ( / \/ $ / , '' ) ,
52
+ title : node . frontmatter . title ,
53
+ tags : node . frontmatter . tags ?? [ ] ,
54
+ date : node . frontmatter . date ,
55
+ authors : ( node . frontmatter . byline ?? '' )
56
+ . split ( ',' )
57
+ . map ( name => name . trim ( ) )
58
+ . filter ( Boolean ) ,
59
+ guestBio : node . frontmatter . guestBio ?? null ,
60
+ } ;
61
+
62
+ createNode ( {
63
+ ...blogPostContent ,
64
+ remark : node . id ,
65
+ parent : node . id ,
66
+ children : [ ] ,
67
+ internal : {
68
+ type : 'BlogPost' ,
69
+ contentDigest : createContentDigest ( blogPostContent ) ,
70
+ } ,
71
+ } ) ;
72
+
73
+ createParentChildLink ( {
74
+ parent : node ,
75
+ child : blogPostContent ,
76
+ } ) ;
77
+ }
78
+ }
79
+ } ;
80
+
8
81
exports . onCreatePage = async ( { page, actions } ) => {
82
+ // trying to refactor code to be "the Gatsby way".
83
+ // from the paths on ready, ignores a bunch of existing custom logic below.
84
+ if ( page . path . startsWith ( '/blog' ) ) {
85
+ return ;
86
+ }
87
+ if ( page . path . startsWith ( '/tags' ) ) {
88
+ return ;
89
+ }
90
+
9
91
const { createPage, deletePage } = actions
10
92
deletePage ( page )
11
93
let context = {
@@ -148,8 +230,8 @@ exports.createPages = async ({ graphql, actions }) => {
148
230
}
149
231
}
150
232
}
151
- tagsGroup: allMarkdownRemark {
152
- group(field: frontmatter___tags ) {
233
+ allBlogPost {
234
+ group(field: tags ) {
153
235
fieldValue
154
236
}
155
237
}
@@ -164,6 +246,17 @@ exports.createPages = async ({ graphql, actions }) => {
164
246
throw result . errors
165
247
}
166
248
249
+ const tags = result . data . allBlogPost . group . map ( group => group . fieldValue )
250
+ tags . forEach ( tag => {
251
+ createPage ( {
252
+ path : `/tags/${ tag . toLowerCase ( ) } /` ,
253
+ component : path . resolve ( "./src/templates/{BlogPost.tags}.tsx" ) ,
254
+ context : {
255
+ tag,
256
+ } ,
257
+ } )
258
+ } )
259
+
167
260
const markdownPages = result . data . allMarkdownRemark . edges
168
261
169
262
// foundation: [
@@ -201,6 +294,15 @@ exports.createPages = async ({ graphql, actions }) => {
201
294
category : "GraphQL Foundation" ,
202
295
} ,
203
296
} ,
297
+ {
298
+ frontmatter : {
299
+ sidebarTitle : "GraphQL Landscape" ,
300
+ title : "GraphQL Landscape" ,
301
+ permalink : "https://landscape.graphql.org/" ,
302
+ date : null ,
303
+ category : "GraphQL Foundation" ,
304
+ } ,
305
+ } ,
204
306
] ,
205
307
} ,
206
308
] ,
@@ -341,7 +443,9 @@ exports.createPages = async ({ graphql, actions }) => {
341
443
342
444
// Use all the set up data to now tell Gatsby to create pages
343
445
// on the site
344
- allPages . forEach ( page => {
446
+ allPages
447
+ . filter ( page => ! page . permalink . startsWith ( '/blog' ) )
448
+ . forEach ( page => {
345
449
createPage ( {
346
450
path : `${ page . permalink } ` ,
347
451
component : docTemplate ,
@@ -353,17 +457,14 @@ exports.createPages = async ({ graphql, actions }) => {
353
457
} ,
354
458
} )
355
459
} )
460
+ }
356
461
357
- // Create tag pages
358
- const tagTemplate = path . resolve ( "src/templates/tags.tsx" )
359
- const tags = result . data . tagsGroup . group
360
- tags . forEach ( tag => {
361
- createPage ( {
362
- path : `/tags/${ tag . fieldValue } /` ,
363
- component : tagTemplate ,
364
- context : {
365
- tag : tag . fieldValue ,
366
- } ,
367
- } )
462
+ exports . onCreateWebpackConfig = ( { actions } ) => {
463
+ actions . setWebpackConfig ( {
464
+ resolve : {
465
+ fallback : {
466
+ "assert" : require . resolve ( "assert/" ) ,
467
+ }
468
+ }
368
469
} )
369
470
}
0 commit comments