2022-07-11 23:24:04 +00:00
|
|
|
const nunjucks = require('nunjucks')
|
|
|
|
|
|
|
|
class NunjucksRenderer {
|
|
|
|
directory
|
|
|
|
environment
|
|
|
|
|
2022-07-12 03:31:59 +00:00
|
|
|
#persistentCaches = new Map()
|
|
|
|
|
2022-07-11 23:24:04 +00:00
|
|
|
constructor (directory = '', options = {}) {
|
|
|
|
if (typeof directory !== 'string') {
|
|
|
|
throw new TypeError('Root directory must be a string value')
|
|
|
|
}
|
|
|
|
|
|
|
|
this.directory = directory
|
|
|
|
|
|
|
|
this.environment = nunjucks.configure(
|
|
|
|
this.directory,
|
|
|
|
Object.assign(options, {
|
|
|
|
autoescape: true
|
|
|
|
})
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#middleware (req, res, next) {
|
|
|
|
// Inject render() method into Response on each requests
|
2022-07-12 03:31:59 +00:00
|
|
|
// If usePersistentCache, the rendered template will be cached forever (thus only use for absolutely static pages)
|
|
|
|
res.render = (path, params, usePersistentCache) => this.#render(res, path, params, usePersistentCache)
|
2022-07-11 23:24:04 +00:00
|
|
|
return next()
|
|
|
|
}
|
|
|
|
|
2022-07-12 03:31:59 +00:00
|
|
|
#render (res, path, params, usePersistentCache) {
|
2022-07-11 23:24:04 +00:00
|
|
|
return new Promise((resolve, reject) => {
|
2022-07-12 03:31:59 +00:00
|
|
|
const template = `${path}.njk`
|
|
|
|
|
|
|
|
const cached = this.#persistentCaches.get(template)
|
|
|
|
if (usePersistentCache && cached) {
|
|
|
|
return resolve(cached)
|
|
|
|
}
|
|
|
|
|
|
|
|
this.environment.render(template, params, (err, html) => {
|
|
|
|
if (err) {
|
|
|
|
return reject(err)
|
|
|
|
}
|
|
|
|
if (usePersistentCache) {
|
|
|
|
this.#persistentCaches.set(template, html)
|
|
|
|
}
|
2022-07-11 23:24:04 +00:00
|
|
|
resolve(html)
|
|
|
|
})
|
|
|
|
}).then(html => {
|
2022-07-12 03:41:58 +00:00
|
|
|
res.type('html').send(html)
|
|
|
|
return html
|
2022-07-11 23:24:04 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
get middleware () {
|
|
|
|
return this.#middleware.bind(this)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = NunjucksRenderer
|