forked from github/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
render-page.js
95 lines (81 loc) · 3.52 KB
/
render-page.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
import { get } from 'lodash-es'
import patterns from '../lib/patterns.js'
import getMiniTocItems from '../lib/get-mini-toc-items.js'
import Page from '../lib/page.js'
import { isConnectionDropped } from './halt-on-dropped-connection.js'
import { nextApp, nextHandleRequest } from './next.js'
export default async function renderPage(req, res, next) {
const page = req.context.page
// render a 404 page
if (!page) {
if (process.env.NODE_ENV !== 'test' && req.context.redirectNotFound) {
console.error(
`\nTried to redirect to ${req.context.redirectNotFound}, but that page was not found.\n`
)
}
return nextApp.render404(req, res)
}
// Just finish fast without all the details like Content-Length
if (req.method === 'HEAD') {
return res.status(200).end()
}
// Is the request for JSON debugging info?
const isRequestingJsonForDebugging = 'json' in req.query && process.env.NODE_ENV !== 'production'
// add page context
const context = Object.assign({}, req.context, { page })
// collect URLs for variants of this page in all languages
context.page.languageVariants = Page.getLanguageVariants(req.pagePath)
// Stop processing if the connection was already dropped
if (isConnectionDropped(req, res)) return
// render page
context.renderedPage = await page.render(context)
// Stop processing if the connection was already dropped
if (isConnectionDropped(req, res)) return
// get mini TOC items on articles
if (page.showMiniToc) {
context.miniTocItems = getMiniTocItems(context.renderedPage, page.miniTocMaxHeadingLevel)
}
// handle special-case prerendered GraphQL objects page
if (req.pagePath.endsWith('graphql/reference/objects')) {
// concat the markdown source miniToc items and the prerendered miniToc items
context.miniTocItems = context.miniTocItems.concat(
req.context.graphql.prerenderedObjectsForCurrentVersion.miniToc
)
context.renderedPage =
context.renderedPage + req.context.graphql.prerenderedObjectsForCurrentVersion.html
}
// handle special-case prerendered GraphQL input objects page
if (req.pagePath.endsWith('graphql/reference/input-objects')) {
// concat the markdown source miniToc items and the prerendered miniToc items
context.miniTocItems = context.miniTocItems.concat(
req.context.graphql.prerenderedInputObjectsForCurrentVersion.miniToc
)
context.renderedPage =
context.renderedPage + req.context.graphql.prerenderedInputObjectsForCurrentVersion.html
}
// Create string for <title> tag
context.page.fullTitle = context.page.titlePlainText
// add localized ` - GitHub Docs` suffix to <title> tag (except for the homepage)
if (!patterns.homepagePath.test(req.pagePath)) {
context.page.fullTitle =
context.page.fullTitle + ' - ' + context.site.data.ui.header.github_docs
}
// `?json` query param for debugging request context
if (isRequestingJsonForDebugging) {
if (req.query.json.length > 1) {
// deep reference: ?json=page.permalinks
return res.json(get(context, req.query.json))
} else {
// dump all the keys: ?json
return res.json({
message:
'The full context object is too big to display! Try one of the individual keys below, e.g. ?json=page. You can also access nested props like ?json=site.data.reusables',
keys: Object.keys(context),
})
}
}
// Hand rendering over to NextJS
req.context.renderedPage = context.renderedPage
req.context.miniTocItems = context.miniTocItems
return nextHandleRequest(req, res)
}