koa v2 的 Nunjucks 设置
Nunjucks setup for koa v2
我有一个 Koa v2 应用程序,其中 koa-views@next
作为渲染器和 nunjucks
模板引擎。这是我的工作设置,没有任何问题,我只是混淆了 views
文件夹的双重声明:
const Koa = require('koa');
const nunjucks = require('nunjucks');
const path = require('path');
const router = require('koa-router')();
const views = require('koa-views');
const app = new Koa();
const index = require('./routes/index');
app.use(views(path.join(__dirname, 'views'), {
extension: 'njk',
map: { njk: 'nunjucks' },
}));
nunjucks.configure(path.join(__dirname, 'views'), {
autoescape: true,
});
router.use('/', index.routes(), index.allowedMethods());
app
.use(router.routes())
.use(router.allowedMethods());
app.listen(3000);
但是如果我不这样做,渲染就不会工作。如果我取消注释 nunjucks.configure
块,我会收到以下错误:
Template render error: (unknown path)
Error: template not found: layout.njk
我的设置有问题吗?
我想出了一个解决方案,可以在 koa v2
中使用 nunjucks
而无需任何其他渲染器库:
/*
USAGE:
import njk from './nunjucks';
// Templating - Must be used before any router
app.use(njk(path.join(__dirname, 'views'), {
extname: '.njk',
noCache: process.env.NODE_ENV !== 'production',
throwOnUndefined: true,
filters: {
json: function (str) {
return JSON.stringify(str, null, 2);
},
upperCase: str => str.toUpperCase(),
},
globals: {
version: 'v3.0.0',
},
}));
*/
// Inspired by:
// https://github.com/ohomer/koa-nunjucks-render/blob/master/index.js
// https://github.com/beliefgp/koa-nunjucks-next/blob/master/index.js
const Promise = require('bluebird');
const nunjucks = require('nunjucks');
function njk(path, opts) {
const env = nunjucks.configure(path, opts);
const extname = opts.extname || '';
const filters = opts.filters || {};
//console.time('benchmark');
const f = Object.keys(filters).length;
let i = 0;
while (i < f) {
env.addFilter(Object.keys(filters)[i], Object.values(filters)[i]);
i += 1;
}
//console.timeEnd('benchmark');
const globals = opts.globals || {};
const g = Object.keys(globals).length;
let j = 0;
while (j < g) {
env.addFilter(Object.keys(globals)[j], Object.values(globals)[j]);
j += 1;
}
return (ctx, next) => {
ctx.render = (view, context = {}) => {
context = Object.assign({}, ctx.state, context);
return new Promise((resolve, reject) => {
env.render(`${view}${extname}`, context, (err, res) => {
if (err) {
return reject(err);
}
ctx.body = res;
return resolve();
});
});
};
return next();
};
}
module.exports = njk;
我有一个 Koa v2 应用程序,其中 koa-views@next
作为渲染器和 nunjucks
模板引擎。这是我的工作设置,没有任何问题,我只是混淆了 views
文件夹的双重声明:
const Koa = require('koa');
const nunjucks = require('nunjucks');
const path = require('path');
const router = require('koa-router')();
const views = require('koa-views');
const app = new Koa();
const index = require('./routes/index');
app.use(views(path.join(__dirname, 'views'), {
extension: 'njk',
map: { njk: 'nunjucks' },
}));
nunjucks.configure(path.join(__dirname, 'views'), {
autoescape: true,
});
router.use('/', index.routes(), index.allowedMethods());
app
.use(router.routes())
.use(router.allowedMethods());
app.listen(3000);
但是如果我不这样做,渲染就不会工作。如果我取消注释 nunjucks.configure
块,我会收到以下错误:
Template render error: (unknown path)
Error: template not found: layout.njk
我的设置有问题吗?
我想出了一个解决方案,可以在 koa v2
中使用 nunjucks
而无需任何其他渲染器库:
/*
USAGE:
import njk from './nunjucks';
// Templating - Must be used before any router
app.use(njk(path.join(__dirname, 'views'), {
extname: '.njk',
noCache: process.env.NODE_ENV !== 'production',
throwOnUndefined: true,
filters: {
json: function (str) {
return JSON.stringify(str, null, 2);
},
upperCase: str => str.toUpperCase(),
},
globals: {
version: 'v3.0.0',
},
}));
*/
// Inspired by:
// https://github.com/ohomer/koa-nunjucks-render/blob/master/index.js
// https://github.com/beliefgp/koa-nunjucks-next/blob/master/index.js
const Promise = require('bluebird');
const nunjucks = require('nunjucks');
function njk(path, opts) {
const env = nunjucks.configure(path, opts);
const extname = opts.extname || '';
const filters = opts.filters || {};
//console.time('benchmark');
const f = Object.keys(filters).length;
let i = 0;
while (i < f) {
env.addFilter(Object.keys(filters)[i], Object.values(filters)[i]);
i += 1;
}
//console.timeEnd('benchmark');
const globals = opts.globals || {};
const g = Object.keys(globals).length;
let j = 0;
while (j < g) {
env.addFilter(Object.keys(globals)[j], Object.values(globals)[j]);
j += 1;
}
return (ctx, next) => {
ctx.render = (view, context = {}) => {
context = Object.assign({}, ctx.state, context);
return new Promise((resolve, reject) => {
env.render(`${view}${extname}`, context, (err, res) => {
if (err) {
return reject(err);
}
ctx.body = res;
return resolve();
});
});
};
return next();
};
}
module.exports = njk;