模板渲染
include子模板
xss过滤
helper函数
- nunjucks 模板引擎,不需要安装
koa-views
koa-nunjucks-2
实例返回一个中间件,这个中间件会让上下文获得一个渲染方法- 从渲染方法参数上获取传递的数据(其次从
ctx.state
获取),然后使用 nunjucks 渲染模板; - 根据用户配置决定是否返回HTML页面
- 从渲染方法参数上获取传递的数据(其次从
koa-nunjucks-2
的一个问题:app.use(nunjucks({}))
必须放在app.use(router.routes()).use(router.allowedMethods())
前面- 否则会报错
ctx.render()
不是一个 function
npm install nunjucks
npm install koa-nunjucks-2
renderString变量
- 如何显示变量 {{ }}
render html
- 渲染文件
- render内部还会调用 renderString
- node 端,’views’ 为相对于当前工作目录 (working directory) 的路径。
a. 在浏览器端则为一个相对的 url,最好指定为绝对路径 (如 ‘/views’) - 默认后缀可以是: index.njk,index.html
filter过滤器
- 过滤器 | 可以执行变量的函数;通过管道符 | 调用,可以接收参数
const filter = nunjucks.renderString("hello {{arr | join('123') | capitalize | replace('ok','good') }}", { arr: ['qijia', 'zhiguo', 'ok'] })
console.log('filter', filter)
/**
* nunjucks
* 中文 https://nunjucks.bootcss.com/getting-started.html
* 英文 http://mozilla.github.io/nunjucks/templating.html#for
*/
const nunjucks = require('nunjucks')
const path = require('path')
const views = path.resolve(__dirname, 'views')
// 第一个参数:指定模板的文件夹
nunjucks.configure(views, {
autoescape: true
})
// 渲染字符串
const res = nunjucks.renderString('123{{user}}', {user: 'lucy'})
console.log('renderString', res) // 123lucy
/**
* 1 如何显示变量 {{ }}
* 2 过滤器 | 可以执行变量的函数;通过管道符 | 调用,可以接收参数
* 3 if 进行逻辑判断
* 4 for 循环
*/
// const filter = nunjucks.renderString("hello {{arr | join('123') | capitalize | replace('ok','good') }}", { arr: ['qijia', 'zhiguo', 'ok'] })
// console.log('filter', filter)
const logic = nunjucks.renderString(`
{{user}}:
{% if score > 90 %}
优秀
{% elif score > 80 %}
良好
{% elif score > 60 %}
及格
{% else %}
要继续努力
{% endif %}
`, {
user: 'lucy',
score: 32
})
console.log('logic', logic)
// 渲染 html模板:render方法内部还会调用 renderString
const html = nunjucks.render('index.html', { user: 'lucy', title: 'node-numjucks'})
console.log('html', html)
if 条件判断
for循环
koa-nunjucks
const koa = require('koa');
const app = new koa();
const koaNunjucks = require('koa-nunjucks-2');
const path = require('path');
app.use(koaNunjucks({
ext: 'html',
path: path.join(__dirname, 'views'),
nunjucksConfig: {
trimBlocks: true
}
}));
app.use(async (ctx) => {
await ctx.render('home', {double: 'rainbow'});
});
异步文件读取,需要使用 await
router.get('view', async (ctx) => {
var food = {
'ketchup': '5 tbsp',
'mustard': '1 tbsp',
'pickle': '0 tbsp'
};
await ctx.render('index',{title:'nunjucks',food});
})
nunjucks原理
const env = nunjucks.configure(config.path, config.nunjucksConfig);
env.renderAsync = bluebird.promisify(env.render);
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();
};
在创建 koa-nunjucks-2 中间件时,可以传递文件后缀 ext
,渲染方法名 functionName
,以及 nunjucks 的配置信息 nunjucksConfig
等
const express = require('express')
const app = express()
// req请求对象 ; res相应对象
app.get('/list', (req, res) => {
const obj = {name: 'lucy'}
res.json(obj)
})
app.listen(3000, () => {
console.log('ok')
})
req.query // 获取 GET参数
req.method // 请求方式
req.path //
app.get()
app.post()
app.put()
无论使用哪种请求方式,服务端都能响应
app.all() // 忽略请求方式
app.all('*', (req, res) => {
res.json({
uri: req.path,
method: req.method
})
})
app.use() // 中间件,路由注册