Implemented sitemaps.
This commit is contained in:
parent
ddf6a3ba63
commit
255e5f7835
22
assets/css/sitemap.css
Normal file
22
assets/css/sitemap.css
Normal 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
16
content/pages/sitemap.njk
Normal 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>
|
28
index.js
28
index.js
|
@ -2,11 +2,10 @@ import fs from 'fs'
|
||||||
import express from 'express'
|
import express from 'express'
|
||||||
|
|
||||||
import njk from 'nunjucks'
|
import njk from 'nunjucks'
|
||||||
import njkMarkdown from 'nunjucks-markdown'
|
|
||||||
import marked from 'marked'
|
|
||||||
|
|
||||||
import { requestHandler } from './libs/requestHandler.js'
|
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
|
// Load in config
|
||||||
|
@ -23,26 +22,11 @@ const Server = express()
|
||||||
// Configure the assets directory
|
// Configure the assets directory
|
||||||
Server.use('/assets', express.static(Config.assetsDir))
|
Server.use('/assets', express.static(Config.assetsDir))
|
||||||
|
|
||||||
// Configure the nunjucks environment (HTML templating)
|
// Configure nunjacks
|
||||||
const njkEnv = njk.configure(
|
nunjacksConfig(njk, Server, Config)
|
||||||
Config.contentDir,
|
|
||||||
{
|
|
||||||
autoescape: true, // Automatically escape HTML aka a '<' will become '<'
|
|
||||||
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 marked (markdown parser)
|
// Generate utils
|
||||||
marked.use({
|
utils.generate()
|
||||||
gfm: true, // Use GitHub formatting?
|
|
||||||
renderer: markedRenderer // Use my own custom rendering for som tags
|
|
||||||
})
|
|
||||||
|
|
||||||
// Let nunjucks use markdown.
|
|
||||||
njkMarkdown.register(njkEnv, marked)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
31
libs/nunjucksConfig.js
Normal file
31
libs/nunjucksConfig.js
Normal 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 '<'
|
||||||
|
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
70
libs/utils/siteMap.js
Normal 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
14
libs/utils/utils.js
Normal 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: {}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user