-
Notifications
You must be signed in to change notification settings - Fork 7
/
index.js
84 lines (72 loc) · 2.49 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/*!
* koa-nunjucks-2
* Copyright (c) 2017 strawbrary
* MIT Licensed
*/
const bluebird = require('bluebird');
const defaults = require('lodash.defaults');
const difference = require('lodash.difference');
const merge = require('lodash.merge');
const path = require('path');
const nunjucks = require('nunjucks');
/**
* @type {!Object}
*/
const defaultSettings = {
ext: 'njk', // Extension that will be automatically appended to the file name in this.render calls. Set to a falsy value to disable.
path: '', // Path to the templates.
writeResponse: true, // If true, writes the rendered output to response.body.
functionName: 'render', // The name of the function that will be called to render the template
nunjucksConfig: {}, // Object of Nunjucks config options.
configureEnvironment: null, // Function to further modify the Nunjucks environment
};
/**
* @param {!Object=} config
*/
module.exports = (config = {}) => {
defaults(config, defaultSettings);
// Sanity check for unknown config options
const configKeysArr = Object.keys(config);
const knownConfigKeysArr = Object.keys(defaultSettings);
if (configKeysArr.length > knownConfigKeysArr.length) {
const unknownConfigKeys = difference(configKeysArr, knownConfigKeysArr);
throw new Error(`Unknown config option: ${unknownConfigKeys.join(', ')}`);
}
if (Array.isArray(config.path)) {
config.path = config.path.map(item => path.resolve(process.cwd(), item));
} else {
config.path = path.resolve(process.cwd(), config.path);
}
if (config.ext) {
config.ext = `.${config.ext.replace(/^\./, '')}`;
} else {
config.ext = '';
}
const env = nunjucks.configure(config.path, config.nunjucksConfig);
env.renderAsync = bluebird.promisify(env.render);
if (typeof config.configureEnvironment === 'function') {
config.configureEnvironment(env);
}
return async (ctx, next) => {
if (ctx[config.functionName]) {
throw new Error(`ctx.${config.functionName} is already defined`);
}
/**
* @param {string} view
* @param {!Object=} context
* @returns {string}
*/
ctx[config.functionName] = async (view, context) => {
const mergedContext = merge({}, ctx.state, context);
view += config.ext;
return env.renderAsync(view, mergedContext)
.then((html) => {
if (config.writeResponse) {
ctx.type = 'html';
ctx.body = html;
}
});
};
await next();
};
};