70 lines
2.3 KiB
JavaScript
70 lines
2.3 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,
|
||
|
address: fullPath.replace(/^[\s\S]+\/pages/, ""),
|
||
|
type: "directory",
|
||
|
children: await handlePath(fullPath, {})
|
||
|
}
|
||
|
else
|
||
|
siteMap[fullPath.replace(/^[\s\S]+\/pages/, "").replace(/\.[a-z]+$/, "")] = {
|
||
|
path: fullPath,
|
||
|
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.address}`)
|
||
|
result.push(renderSiteMap(dir.children, entrypoint))
|
||
|
result.push(`</a>`)
|
||
|
} else {
|
||
|
result.push(`<a href="${dir.address}">${dir.address}</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)
|
||
|
}
|
||
|
}
|