forked from github/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
current-product-tree.js
121 lines (110 loc) · 4.14 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
import path from 'path'
import liquid from '../../lib/render-content/liquid.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
)
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
}