forked from github/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcurrent-product-tree.js
139 lines (126 loc) · 4.71 KB
/
current-product-tree.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
import path from 'path'
import { liquid } from '#src/content-render/index.js'
import findPageInSiteTree from '../../lib/find-page-in-site-tree.js'
import removeFPTFromPath from '../../lib/remove-fpt-from-path.js'
import { executeWithFallback } from '../../lib/render-with-fallback.js'
// This module adds currentProductTree to the context object for use in layouts.
export default async function currentProductTree(req, res, next) {
if (!req.context.page) return next()
if (req.context.page.documentType === 'homepage') return next()
// We need this so we can fall back to English if localized pages are out of sync.
req.context.currentEnglishTree = req.context.siteTree.en[req.context.currentVersion]
const currentRootTree =
req.context.siteTree[req.context.currentLanguage][req.context.currentVersion]
const currentProductPath = removeFPTFromPath(
path.posix.join(
'/',
req.context.currentLanguage,
req.context.currentVersion,
req.context.currentProduct,
),
)
req.context.currentProductTree = findPageInSiteTree(
currentRootTree,
req.context.currentEnglishTree,
currentProductPath,
)
// First make a slim tree of just the 'href', 'title', 'shortTitle'
// 'documentType' and 'childPages' (which is recursive).
// This gets used for map topic and category pages.
req.context.currentProductTreeTitles = await getCurrentProductTreeTitles(
req.context.currentProductTree,
req.context,
)
// Now make an even slimmer version that excludes all hidden pages.
// This is i used for sidebars.
req.context.currentProductTreeTitlesExcludeHidden = excludeHidden(
req.context.currentProductTreeTitles,
)
// Some pages, like hidden pages, don't have a tree. For example,
// the search page. That one uses the same items as the homepage
// for its sidebar.
if (req.context.currentProductTreeTitlesExcludeHidden) {
req.context.sidebarTree = sidebarTree(req.context.currentProductTreeTitlesExcludeHidden)
}
return next()
}
// Return a nested object that contains the bits and pieces we need
// for the tree which is used for sidebars and listing
async function getCurrentProductTreeTitles(input, context) {
const { page, href } = input
const childPages = await Promise.all(
(input.childPages || []).map((child) => getCurrentProductTreeTitles(child, context)),
)
// If the current page is a translation we're going to need the English
// equivalent for multiple things later in this function.
const enPage =
page.languageCode !== 'en' ? context.pages[href.replace(`/${page.languageCode}`, '/en')] : null
let rawShortTitle = page.rawShortTitle // might change our minds about this
// A lot of translations have a short title that is identical to the
// English equivalent. E.g.
//
// content/foo.md:
//
// title: Something Something Bla
// shortTitle: Something
//
// translations/docs-internal.se-sv/content/foo.md:
//
// title: Nånting Nånting Blä
// shortTitle: Something
//
// I.e. the translations `shortTitle` hasn't been translated.
// If this is the case, use the long title instead.
if (page.languageCode !== 'en' && page.rawShortTitle) {
if (page.rawShortTitle === enPage.shortTitle) {
rawShortTitle = page.rawTitle
}
}
const renderedFullTitle = await executeWithFallback(
context,
() => liquid.parseAndRender(page.rawTitle, context),
(enContext) => liquid.parseAndRender(enPage.rawTitle, enContext),
)
let renderedShortTitle = ''
if (rawShortTitle) {
renderedShortTitle = await executeWithFallback(
context,
() => liquid.parseAndRender(page.rawShortTitle, context),
(enContext) => liquid.parseAndRender(enPage.rawShortTitle, enContext),
)
}
// If the short title was present but "useless" (same as the title),
// force it to be an empty string to not waste space.
const shortTitle =
renderedShortTitle && (renderedShortTitle || '') !== renderedFullTitle ? renderedShortTitle : ''
const node = {
href: input.href,
title: renderedFullTitle,
shortTitle,
documentType: page.documentType,
childPages: childPages.filter(Boolean),
}
if (page.hidden) node.hidden = true
return node
}
function excludeHidden(tree) {
if (tree.hidden) return null
const newTree = {
href: tree.href,
title: tree.title,
shortTitle: tree.shortTitle,
documentType: tree.documentType,
childPages: tree.childPages.map(excludeHidden).filter(Boolean),
}
return newTree
}
function sidebarTree(tree) {
const { href, title, shortTitle, childPages } = tree
const childChildPages = childPages.map(sidebarTree)
const newTree = {
href,
title: shortTitle || title,
childPages: childChildPages,
}
return newTree
}