Nunjucks在Koa中的应用
- app.js
const koa = require('koa');
const app = new koa();
const router = require('./router')
const nunjucks = require('koa-nunjuncks-2');
app.use(nunjucks({ext: 'html', // 指定视图文件默认后缀path: path.join(__dirname, 'views'), // 指定视图目录nunjucksConfig:{trimBlocks: true // 开启转义,防止XSS}
}))
注: 配置要在router前面
- 使用 (ctx.render(path))
- /controller/home.js
user: async (ctx, next) =>{await ctx.render('home/login',{btnName: 'GoGoGo'})
}
关键代码
- 使用&&挂载&&配置nunjucks
const nunjucks = require('koa-nunjucks-2');
app.use(nunjucks({ext: 'html', // 默认的后缀名path: path.join(__dirname, 'views'),nunjucksConfig:{trimBlocks: true // 开启转义,防止XSS}
}));
- views的目录结构如下
- 例如使用 /views/home/login.html 模板进行渲染
async (ctx, next) =>{awaite ctx.render('home/login',{btnName: 'GoGoGo'})
}
- /views/home/login.html
{% extends "common/layout-home.html" %}
{% block homeBanner %}
<div class="banner_box"><div class="banner_inner"><h2 class="slogan">汇聚天下英才</h2><p class="des">吃货吃货 Marron<br>好吃不贵,多吃不胖!!!</p><a href="/login" title="gogogo" class="btn" id="gogogo">进入战场</a></div>
</div>
{% endblock %}
{% block content %}
<div class="hp-dialog"><div class="hp-box"><form action="/user/login" method="post"><h1>到达战场</h1><p class="error">{{content}}</p><input type="text" name="name" placeholder="请输入用户名:marron"><input type="password" name="password" placeholder="请输入密码:123456"><button>GoGoGo</button></form></div>
</div>
<div class="hp-overlay"></div>
{% endblock %}
Nunjucks语法介绍
一般情况下,模板引擎都需要具备以下功能: 变量、逻辑表达式、循环、layout、include、宏和扩展等.
1.文件扩展名
Nunjucks支持用任意扩展名来命名模板文件,但Nunjucks社区还是推荐使用’.njk’为后缀进行命名
2.变量
变量会从模板文件运行时的上下文获取,如果需要显示一个变量,代码如下:
{{username}}
模板文件运行时,会从上下文对象中查找username属性,然后显示。模板语法也支持像JavaScript一样获取变量的属性(可使用点操作符或中括号操作符),代码如下:
{{foo.bar}}
{{foo["bar"]}}
如果变量的值为undefined或null将不予显示,引用的对象为undefined或null也是如此,
3.注释
在Nunjucks模板语法中,可以使用语法{# 注释内容 #}
来编写注释,注释不会被编译,示例代码如下:
{# Loop through all the users #}
{% for user in users %}...{% endfor %}
模板文件运行后只会渲染第2行的文本内容。
4.标签
标签是一些特殊的区块,应用标签可以对模板执行一些操作。Nunjucks包含一些内置的标签,同时也支持自定义标签。
- if标签
if为分支语句,与JavaScript中的if语句类似,代码如下:
{% if variable %}It is true
{% endif %}
如果variable已经被定义且为true,则会显示"It is true",否则什么也不显示。
注意: 这里并非布尔值,和JavaScript的处理是一样的。
````javascript
{% if hungry %}I am hungry!
{% elif tired %}I am tired!
{% else %}I am good!
{% endif %}
- for标签
for可以用来遍历数组和对象。假设遍历如下数组:
var items = [{ title: "foo", id: 1}, { title: "bar", id:2 }];
对应的模板代码如下:
<h1>Posts</h1>
<ul>
{% for item in items %}<li>{{ item.title }}</li>
{% else %}<li>This would display if the 'item' collection were empty</li>
{% endfor %}
</ul>
上面的示例通过for循环调用items数组中的每个元素,并将对应元素的title属性显示出来。如果items是空数组,则会渲染else语句中的内容。- macro(宏)标签
宏: 定义可复用的内容,类似于编程语言中的函数,示例代码如下:
````javascript
{% macro field(name, value='', type='text') %}
<div class="field">
<input type="{{ type }}" name="{{ name }}" value="{{ value | escape }}" />
</div>
{% endmacro %}
接下来就可以把field当作函数一样使用了,代码如下:
{{ field('user') }}
{{ field('pass', type='password') }}
- Extends/Block标签
Extends用来指定模板继承,被指定的模板为父级模板。Block(区块)定义了模板片段并标识一个名字,在模板继承中使用。父级模板可指定一个区块,子模板覆盖这个区块。Extends标签和Block标签相互搭配,在模板继承场景中经常会被用到。在实战项目中,经常需要设定一个固定的公用模板Layout,然后开发人员再创建一个业务级的模板文件,并把Layout继承过来。公用模板文件layout.html的示例代码如下:
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge">{% block head %}<link rel="stylesheet">{% endblock %}
</head>
<body>{% block header %}<h1>this is header</h1>{% endblock %}{% block body %}<h1>this is body</h1><% endblock %><% block footer %><h1>this is footer</h1><% endblock %><% block content %><script>// this is place for javascript</script>{% endblock %}
</body>
</html>