forked from github/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
breadcrumbs.js
87 lines (75 loc) · 2.87 KB
/
breadcrumbs.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
import liquid from '../../lib/render-content/liquid.js'
export default async function breadcrumbs(req, res, next) {
if (!req.context.page) return next()
const isEarlyAccess = req.context.page.relativePath.startsWith('early-access')
if (req.context.page.hidden && !isEarlyAccess) return next()
req.context.breadcrumbs = []
// Return an empty array on the landing page.
if (req.context.page.documentType === 'homepage') {
return next()
}
req.context.breadcrumbs = await getBreadcrumbs(req, isEarlyAccess)
return next()
}
const earlyAccessExceptions = ['insights', 'enterprise-importer']
async function getBreadcrumbs(req, isEarlyAccess = false) {
const crumbs = []
const { currentPath, currentVersion } = req.context
const split = currentPath.split('/')
let cutoff = 2
if (isEarlyAccess) {
// When in Early access docs consider the "root" be much higher.
// E.g. /en/early-access/github/migrating/understanding/about
// we only want it start at /migrating/understanding/about
// Essentially, we're skipping "/early-access" and its first
// top-level like "/github"
cutoff++
// There are a few exceptions to this rule for the
// /{version}/early-access/<product-name>/... URLs because they're a
// bit different.
// If there are more known exceptions, add them to the array above.
if (!earlyAccessExceptions.some((product) => split.includes(product))) {
cutoff++
}
// If the URL is early access AND has a version in it, go even further
// E.g. /en/[email protected]/early-access/admin/hosting/mysql
// should start at /hosting/mysql.
if (currentVersion !== 'free-pro-team@latest') {
cutoff++
}
}
while (split.length > cutoff && split[split.length - 1] !== currentVersion) {
const href = split.join('/')
const page = req.context.pages[href]
if (page) {
crumbs.push({
href,
title: await getShortTitle(page, req.context),
})
} else {
console.warn(`No page found with for '${href}'`)
}
split.pop()
}
crumbs.reverse()
return crumbs
}
async function getShortTitle(page, context) {
// Note! Don't use `page.title` or `page.shortTitle` because if they get
// set during rendering, they become the HTML entities encoded string.
// E.g. "Delete & restore a package"
if (page.rawShortTitle) {
if (page.rawShortTitle.includes('{')) {
// Can't easily cache this because the `page` is reused for multiple
// permalinks. We could do what the `Page.render()` method does which
// specifically caches based on the `context.currentPath` but at
// this point it's probably not worth it.
return await liquid.parseAndRender(page.rawShortTitle, context)
}
return page.rawShortTitle
}
if (page.rawTitle.includes('{')) {
return await liquid.parseAndRender(page.rawTitle, context)
}
return page.rawTitle
}