You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
70 lines
1.6 KiB
70 lines
1.6 KiB
|
|
'use strict'; |
|
|
|
const nunjucks = require('nunjucks'); |
|
const { readFileSync } = require('hexo-fs'); |
|
const { dirname } = require('path'); |
|
|
|
function toArray(value) { |
|
if (Array.isArray(value)) { |
|
// Return if given value is an Array |
|
return value; |
|
} else if (typeof value.toArray === 'function') { |
|
return value.toArray(); |
|
} else if (value instanceof Map) { |
|
const arr = []; |
|
value.forEach(v => arr.push(v)); |
|
return arr; |
|
} else if (value instanceof Set || typeof value === 'string') { |
|
return [...value]; |
|
} else if (typeof value === 'object' && value instanceof Object && Boolean(value)) { |
|
return Object.values(value); |
|
} |
|
|
|
return []; |
|
} |
|
|
|
function safeJsonStringify(json, spacer = undefined) { |
|
if (typeof json !== 'undefined' && json !== null) { |
|
return JSON.stringify(json, null, spacer); |
|
} |
|
|
|
return '""'; |
|
} |
|
|
|
const nunjucksCfg = { |
|
autoescape: false, |
|
throwOnUndefined: false, |
|
trimBlocks: false, |
|
lstripBlocks: false |
|
}; |
|
|
|
const nunjucksAddFilter = env => { |
|
env.addFilter('toarray', toArray); |
|
env.addFilter('safedump', safeJsonStringify); |
|
}; |
|
|
|
function njkCompile(data) { |
|
let env; |
|
if (data.path) { |
|
env = nunjucks.configure(dirname(data.path), nunjucksCfg); |
|
} else { |
|
env = nunjucks.configure(nunjucksCfg); |
|
} |
|
nunjucksAddFilter(env); |
|
|
|
const text = 'text' in data ? data.text : readFileSync(data.path); |
|
|
|
return nunjucks.compile(text, env, data.path); |
|
} |
|
|
|
function njkRenderer(data, locals) { |
|
return njkCompile(data).render(locals); |
|
} |
|
|
|
njkRenderer.compile = data => { |
|
// Need a closure to keep the compiled template. |
|
return locals => njkCompile(data).render(locals); |
|
}; |
|
|
|
module.exports = njkRenderer;
|
|
|