qwik-site-bubben/libs/utils/siteMap.js

73 lines
2.6 KiB
JavaScript

import fs from 'fs/promises'
import path from 'path'
async function handlePath(dirName, siteMap) {
// Get all directories in the 'dirName'
const dirs = await fs.readdir(dirName)
// For each file in the directory: check if it is a
// file or a folder, if a folder recursively run this
// function in that folder.
for (const dirIndex in dirs) {
const file = dirs[dirIndex]
const fullPath = path.join(dirName, file)
const fileStats = await fs.stat(fullPath)
if (fileStats.isDirectory())
siteMap[fullPath.replace(/^[\s\S]+\/pages/, "")] = {
path: fullPath.replace(/^[\s\S]+\/pages/, "").replace(/\/.+\//, "/"),
address: fullPath.replace(/^[\s\S]+\/pages/, ""),
type: "directory",
children: await handlePath(fullPath, {})
}
else
// Check if it already exists
siteMap[fullPath.replace(/^[\s\S]+\/pages/, "").replace(/\.[a-z]+$/, "")] ?
siteMap[fullPath.replace(/^[\s\S]+\/pages/, "").replace(/\.[a-z]+$/, "")] :
siteMap[fullPath.replace(/^[\s\S]+\/pages/, "").replace(/\.[a-z]+$/, "")] = {
path: fullPath.replace(/^[\s\S]+\/pages/, "").replace(/\.[a-z]+$/, "").replace(/\/.+\//, "/"),
address: fullPath.replace(/^[\s\S]+\/pages/, "").replace(/\.[a-z]+$/, ""),
type: "file"
}
}
return siteMap
}
function renderSiteMap(siteMap, entrypoint) {
// Make a template for the sitemap and recursively run
// for all directories with children.
return `
<div class="sitemap-dir">
${(() => {
let result = []
for (const dirIndex in siteMap) {
const dir = siteMap[dirIndex]
if (!dir.address.startsWith(entrypoint))
continue
if (dir.type === "directory") {
result.push(`<a href="${dir.address}">${dir.path}`)
result.push(renderSiteMap(dir.children, entrypoint))
result.push(`</a>`)
} else {
result.push(`<a href="${dir.address}">${dir.path}</a>`)
}
}
return result.join("")
})()}
</div>
`
}
export async function generateSiteMap(Config) {
// Generate a site map and return it and a render-function.
const siteMap = await handlePath(`${Config.contentDir}/pages`, {})
return {
siteMap,
render: entrypoint => renderSiteMap(siteMap, entrypoint)
}
}