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>