-
Notifications
You must be signed in to change notification settings - Fork 10.3k
/
create-routes.coffee
150 lines (134 loc) · 5.22 KB
/
create-routes.coffee
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
Router = require 'react-router'
filter = require 'lodash/collection/filter'
sortBy = require 'lodash/collection/sortBy'
last = require 'lodash/array/last'
includes = require 'underscore.string/include'
{ config } = require 'config'
module.exports = (pages, pagesReq) ->
templates = {}
templates.root = Router.createRoute({
name: 'root-template'
path: "/"
handler: pagesReq './_template'
})
# Adds a handler for <NotFoundRoute /> that will serve as a 404 Page
if config.notFound
templates.rootNotFound = Router.createNotFoundRoute({
name: 'root-not-found'
path: "*"
handler: pagesReq './_404'
parentRoute: templates.root
})
# Adds a handler for <Route path="page/*" /> for pagination
if config.pagination
templates.rootPagination = Router.createRoute({
name: "root-pagination"
path: "page/:pageId"
parentRoute: templates.root
handler: pagesReq './_pagination'
})
# Adds a handler for <Route path="tag/*" /> for pages tagging
if config.tags
templates.rootTags = Router.createRoute({
name: "root-tags"
path: "tag/:tagId"
parentRoute: templates.root
handler: pagesReq './_tag'
})
# Arrange pages in data structure according to their position
# on the file system. Then use this to create routes.
#
# Algorithm
# 1. Find all templates.
# 2. Create routes for each template russian-doll style.
# 3. For each index file paired with a template, create a default route
# 4. Create normal routes for each remaining file under the appropriate
# template
templateFiles = filter pages, (page) ->
page.file.name is "_template" and
page.file.dirname isnt "."
for templateFile in templateFiles
# Find the parent template of this template.
parentTemplates = filter(templateFiles, (template) ->
includes(templateFile.requirePath, template.file.dirname)
)
parentTemplates = sortBy(parentTemplates, (template) ->
template?.file.dirname.length)
parentTemplateFile = last(parentTemplates)
parentRoute = templates[parentTemplateFile?.file.dirname]
unless parentRoute
parentRoute = templates.root
templates[templateFile.file.dirname] = Router.createRoute({
name: templateFile.file.dirname + "-template"
path: templateFile.templatePath
parentRoute: parentRoute
handler: pagesReq "./" + templateFile.requirePath
})
# Adds a handler for <Route path="page/*" /> (for each templateFile) for pagination
if config.pagination
templates[templateFile.file.dirname + "-pagination"] = Router.createRoute({
name: templateFile.file.dirname + "-pagination"
path: templateFile.templatePath + "page/:pageId"
parentRoute: templates[templateFile.file.dirname]
handler: pagesReq "./" + templateFile.file.dirname + "/_pagination"
})
# Remove files that start with an underscore as this indicates
# the file shouldn't be turned into a page.
filteredPages = filter pages, (page) -> page.file.name.slice(0,1) isnt '_'
markdownWrapper = require 'wrappers/md'
htmlWrapper = require 'wrappers/html'
for page in filteredPages
# TODO add ways to load data for other file types.
# Should be able to install a gatsby-toml plugin to add support
# for TOML. Perhaps everything other than JSX and Markdown should be plugins.
# Or even they are plugins but they have built-in "blessed" plugins.
switch page.file.ext
when "md"
handler = markdownWrapper
page.data = pagesReq "./" + page.requirePath
when "html"
handler = htmlWrapper
when "jsx"
handler = pagesReq "./" + page.requirePath
page.data = if pagesReq("./" + page.requirePath).metadata
pagesReq("./" + page.requirePath).metadata()
when "cjsx"
handler = pagesReq "./" + page.requirePath
page.data = if pagesReq("./" + page.requirePath).metadata
pagesReq("./" + page.requirePath).metadata()
else
handler = pagesReq "./" + page.requirePath
# Determine parent template for page.
parentRoutes = filter(templateFiles, (templateFile) ->
includes(page.requirePath, templateFile.file.dirname)
)
parentRoutes = sortBy(parentRoutes, (route) -> route?.file.dirname.length)
parentTemplateFile = last(parentRoutes)
parentRoute = templates[parentTemplateFile?.file.dirname]
unless parentRoute
parentRoute = templates.root
if page.data and page.data.redirect
# Adds a handler for <Redirect from="some/where" to="somewhere/else" /> where page has a `redirect` metadata
Router.createRedirect({
name: page.path
from: page.path
to: page.data.redirect
parentRoute: parentRoute
})
# If page is an index page *and* in the same directory as a template,
# it is the default route (for that template).
else if includes(page.path, "/index") and
parentRoute.file.dirname is parentTemplateFile.file.dirname
Router.createDefaultRoute({
name: page.path
parentRoute: parentRoute
handler: handler
})
else
Router.createRoute({
name: page.path
path: page.path
parentRoute: parentRoute
handler: handler
})
return templates.root