130 lines
3.9 KiB
JavaScript
130 lines
3.9 KiB
JavaScript
import allLanguages from '../../../config/languages.json' assert { type: 'json' }
|
|
import path from 'path'
|
|
import fs from 'fs'
|
|
import set from 'lodash.set'
|
|
import orderBy from 'lodash.orderby'
|
|
import { extendSiteNav as dev } from './sitenav-dev.mjs'
|
|
import { extendSiteNav as org } from './sitenav-org.mjs'
|
|
import { extendSiteNav as lab } from './sitenav-lab.mjs'
|
|
import { pageHasChildren } from '../utils.mjs'
|
|
import { header } from './shared.mjs'
|
|
|
|
const extendNav = { dev, org, lab }
|
|
|
|
/*
|
|
* A method to recursively add the ordered slugs to the LUT
|
|
*/
|
|
const flattenOrderedChildPages = (nav) => {
|
|
const slugs = []
|
|
for (const page of orderBy(nav, ['o', 't'], ['asc', 'asc'])) {
|
|
if (page.s) {
|
|
slugs.push(page.s)
|
|
if (pageHasChildren(page)) slugs.push(...flattenOrderedChildPages(page))
|
|
}
|
|
}
|
|
|
|
return slugs
|
|
}
|
|
|
|
/*
|
|
* This builds the slugLut (slug look up table) which makes it trivial to
|
|
* build the PrevNext component as it builds a flat list of all pages in
|
|
* the order they are naturally presented to the reader. So if you have
|
|
* a page's slug, you merely need to look it up in the list and return the
|
|
* next entry (or previous)
|
|
*/
|
|
export const orderedSlugLut = (nav) => {
|
|
const slugs = []
|
|
for (const page of orderBy(nav, ['o', 't'], ['asc', 'asc'])) {
|
|
if (page.s) {
|
|
slugs.push(page.s)
|
|
if (pageHasChildren(page)) slugs.push(...flattenOrderedChildPages(page))
|
|
}
|
|
}
|
|
|
|
return slugs
|
|
}
|
|
|
|
/*
|
|
* Main method that does what needs doing
|
|
*/
|
|
export const prebuildNavigation = async (store) => {
|
|
const { site, docs = false, posts = false } = store
|
|
/*
|
|
* Since this is written to disk and loaded as JSON, we minimize
|
|
* the data to load by using the following 1-character keys:
|
|
*
|
|
* t: title
|
|
* o: order, optional
|
|
* s: slug without leading or trailing slash (/)
|
|
*/
|
|
const sitenav = {}
|
|
const all = {
|
|
sitenav: '',
|
|
}
|
|
const locales = docs ? Object.keys(docs) : allLanguages
|
|
for (const lang of locales) {
|
|
sitenav[lang] = {}
|
|
|
|
// Handle docs if there are any
|
|
if (docs[lang]) {
|
|
for (const slug of Object.keys(docs[lang]).sort()) {
|
|
const page = docs[lang][slug]
|
|
const val = {
|
|
t: page.t,
|
|
s: slug,
|
|
}
|
|
if (page.o) val.o = page.o
|
|
set(sitenav, [lang, ...slug.split('/')], val)
|
|
}
|
|
}
|
|
|
|
// Handle posts if there are any
|
|
if (posts) {
|
|
for (const type in posts) {
|
|
for (const [slug, post] of Object.entries(posts[type].posts[lang])) {
|
|
set(sitenav, [lang, ...slug.split('/')], { t: post.t, o: post.o, s: slug })
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add imports for umbrella file
|
|
all.sitenav += `import { siteNav as ${lang} } from './sitenav.${lang}.mjs'` + '\n'
|
|
// Extend navigation if there's a method for that
|
|
if (extendNav[site]) sitenav[lang] = await extendNav[site](sitenav[lang], lang)
|
|
|
|
// Write out navigation object
|
|
fs.writeFileSync(
|
|
path.resolve('..', site, 'prebuild', `sitenav.${lang}.mjs`),
|
|
`${header}export const siteNav = ${JSON.stringify(sitenav[lang])}`
|
|
)
|
|
|
|
/*
|
|
* Since slugs are language-agnostic, we only need to create a slug lookup tables
|
|
* once, for which we'll use the EN locale as that one is always present
|
|
*/
|
|
if (lang === 'en') {
|
|
const sluglut = orderedSlugLut(sitenav[lang])
|
|
// Write out slug lookup table (sluglut)
|
|
fs.writeFileSync(
|
|
path.resolve('..', site, 'prebuild', `sluglut.mjs`),
|
|
`${header}export const slugLut = ${JSON.stringify(sluglut)}`
|
|
)
|
|
store.navigation = { sluglut }
|
|
}
|
|
}
|
|
|
|
// Write umbrella siteNav file
|
|
fs.writeFileSync(
|
|
path.resolve('..', site, 'prebuild', `sitenav.mjs`),
|
|
`${header}${all.sitenav}export const siteNav = { ${locales.join(',')} }`
|
|
)
|
|
|
|
// In the lab, there will be no navigation set in the store
|
|
if (!store.navigation) store.navigation = {}
|
|
|
|
// Update the store
|
|
store.navigation.sitenav = sitenav
|
|
|
|
return
|
|
}
|