I've always had problems with full blown blog systems whether they required to many resources or it took to long to implement simple features. So I took it upon myself to create a simple static-page generator in a day with a few goals:
After a few comparisons I settled for pug.js and started writing some node.js code to compile my pug files to html.
// get all posts
let posts = fs.readdirSync(postDir);
// for each post
for(let f of posts)
{
// compile the pug file
let c = pug.compileFile(path.join(postDir,f,"/post.pug"),{pretty:true});
let html = c();
fs.writeFileSync(path.join(distDir,f+".html"),html);
}
That was easy!
Since I am not too familiar with pug and I always wanted to get my hands dirty with browser-sync I wrote a simple watch.js file which watches all files and runs a given task.
const bs = require("browser-sync").create();
const build = require("./build");
function fn(event, file)
{
// call the build script
build();
// forcefully reload the browser
bs.reload();
}
// servce and watch for files
bs.init({
server: "./dist",
files: [
{
match:"./site/**/*.pug",
fn: fn
},
{
match:"./site/**/*.json",
fn: fn
}
]
});
The above script and a simple task in the package.json now compiles all files, serves them on port 3000 and refreshes the browser whenever a file is changed.
Thanks to pugs templating system it supports a json which can be passed to the rendering function
let {title, description, keywords} = require("../site/posts/"+f+"/data.json");
let html = c({title, description, keywords});
So I can simply put all additional data I may need into the data.json and use its content in the pug template as variables.
To organize multiple posts and being able to creat an index page I came up with a simple Id system which takes the current time in seconds and converts it to a hex string.
let seconds = new Date().getTime();
// 1559384440202
let hexId = seconds.toString(16);
// '16b128e3d8a'
As an optional step for posts like this I wanted to have syntax highlighting and therefore added an assets folder which gets bundled and contains prism.js. So I easily include it via script tags.
This setup took me a good portion of an afternoon to finish but still leaves a few features open to finish like using templates for html meta-data and footer in pug and a cleanup of the js code. But all in all thats what I needed so ¯\_(ツ)_/¯