Write You a Static Site Generator
@adamisntdead
tinyurl.com/node-static
{
"title": "Your Awesome title",
"description": "Write an awesome description here!",
"author": "Author Name",
"static": "assets",
"public": "public"
}
const fs = require('fs-extra')
async function getConfig() {
// Reading the 'config.json' file,
// and parsing the JSON
return await fs.readJSON('config.json')
}
class Site {
constructor(config) {
this.config = config
this.pages = []
this.output = []
}
// Main Method - Builds the site
build() {
...
}
...
}
getConfig()
.then(config => new Site(config))
.then(site => site.build())
.catch(err => console.log(err))
class Site {
...
async build() {
await this.reset()
await this.read()
await this.render()
await this.write()
}
async reset() {
...
}
async read() {
...
}
async render() {
...
}
async write() {
...
}
}
async reset() {
// Delete the public / output directory
await fs.remove(this.config.public)
// Create a new, empty public directory
await fs.mkdirp(this.config.public)
}
const matter = require('gray-matter')
const slug = require('slug')
const glob = require('fast-glob')
...
async read() {
// Read the files in the content directory
const files = await glob('**/*', { cwd: 'content' })
for (const filename of files) {
const fileContent = await fs.readFile(`content/${filename}`, 'utf8')
// Getting the frontmatter
const { content, data } = matter(fileContent)
const title = data.title
const permalink = slug(title).toLowerCase()
// Add the page to the 'this.pages' object
this.pages.push({
title,
permalink,
content,
...frontmatter.data
})
}
}
async render() {
const site = { pages: this.pages, ...this.config }
for (const page in this.pages) {
let content = Handlebars.compile(page.content)({ site, page })
if (page.markdown) {
content = marked(renderedContent)
}
if (page.layout) {
const layout = await fs.readFile(`layouts/${page.layout}.hbs`, 'utf8')
const template = Handlebars.compile(layout)
content = template({ site, page, content })
}
this.output.push({
path: path.join(this.config.public, page.permalink, 'index.html'),
content
})
}
}
async write() {
const outputs = []
for (const output in this.output) {
outputs.push(fs.outputFile(output.path, output.content))
}
return Promise.all(outputs)
}
@adamisntdead
tinyurl.com/node-static