Implemented sitemaps.

master
BurnyLlama 2021-08-09 16:55:53 +02:00
parent ddf6a3ba63
commit 255e5f7835
6 changed files with 159 additions and 22 deletions

22
assets/css/sitemap.css Normal file
View File

@ -0,0 +1,22 @@
body {
display: flex;
flex-direction: column;
}
.sitemap-container {
display: grid;
place-items: center;
width: fit-content;
margin: 2rem auto;
padding: 1rem 4rem;
background-color: var(--grey3);
border-radius: .5rem;
box-shadow: 0 1rem 2rem var(--grey1);
}
.sitemap-dir > .sitemap-dir {
margin: 0 auto;
padding: 0 0 .5rem 1rem;
}

16
content/pages/sitemap.njk Normal file
View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
{% include "templates/defaultTags.njk" %}
<link rel="stylesheet" type="text/css" href="/assets/css/sitemap.css">
<title>Site Map</title>
</head>
<body>
<header>
Sitemap - "/"
</header>
<div class="sitemap-container">
{{ siteMap() | safe }}
</div>
</body>
</html>

View File

@ -2,11 +2,10 @@ import fs from 'fs'
import express from 'express'
import njk from 'nunjucks'
import njkMarkdown from 'nunjucks-markdown'
import marked from 'marked'
import { requestHandler } from './libs/requestHandler.js'
import { markedRenderer } from './libs/markedRenderer.js'
import { utils } from './libs/utils/utils.js'
import { nunjacksConfig } from './libs/nunjucksConfig.js'
// Load in config
@ -23,26 +22,11 @@ const Server = express()
// Configure the assets directory
Server.use('/assets', express.static(Config.assetsDir))
// Configure the nunjucks environment (HTML templating)
const njkEnv = njk.configure(
Config.contentDir,
{
autoescape: true, // Automatically escape HTML aka a '<' will become '&lt;'
watch: true, // Automatically reload all templates if they change on disk.
trimBlocks: true, // Remove trailing newlines from tags
lstripBlocks: true, // Automatically remove leading whitespace from tags
express: Server // Use the express server. (Currently obsolete, I think.)
}
)
// Configure nunjacks
nunjacksConfig(njk, Server, Config)
// Configure marked (markdown parser)
marked.use({
gfm: true, // Use GitHub formatting?
renderer: markedRenderer // Use my own custom rendering for som tags
})
// Let nunjucks use markdown.
njkMarkdown.register(njkEnv, marked)
// Generate utils
utils.generate()

31
libs/nunjucksConfig.js Normal file
View File

@ -0,0 +1,31 @@
import njkMarkdown from 'nunjucks-markdown'
import marked from 'marked'
import { markedRenderer } from './markedRenderer.js'
import { utils } from './utils/utils.js'
export function nunjacksConfig(njk, express, Config) {
// Configure the nunjucks environment (HTML templating)
const njkEnv = njk.configure(
Config.contentDir,
{
autoescape: true, // Automatically escape HTML aka a '<' will become '&lt;'
watch: true, // Automatically reload all templates if they change on disk.
trimBlocks: true, // Remove trailing newlines from tags
lstripBlocks: true, // Automatically remove leading whitespace from tags
express: express // Use the express server. (Currently obsolete, I think.)
}
)
njkEnv.addGlobal('siteMap', entrypoint => utils.values.siteMap.render(entrypoint ? entrypoint : "/"))
// Configure marked (markdown parser)
marked.use({
gfm: true, // Use GitHub formatting?
renderer: markedRenderer // Use my own custom rendering for som tags
})
// Let nunjucks use markdown.
njkMarkdown.register(njkEnv, marked)
}

70
libs/utils/siteMap.js Normal file
View File

@ -0,0 +1,70 @@
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)
}
}

14
libs/utils/utils.js Normal file
View File

@ -0,0 +1,14 @@
import fs from 'fs'
import { generateSiteMap } from './siteMap.js'
const ConfigFile = fs.readFileSync('./config.json')
const Config = JSON.parse(ConfigFile)
// Generate some utilities
export let utils = {
generate: async () =>
utils.values = {
siteMap: await generateSiteMap(Config)
},
values: {}
}