Koa中間件使用之koa-nunjucks-2

Koa-nunjucks-2Koa 的一個輕量級 Nunjucks 中間件,可以用來作為模板引擎,為 koa 應(yīng)用提供頁面渲染功能。

那么,koa-nunjucks-2 做了什么?

  1. 通過創(chuàng)建 koa-nunjucks-2 實例會返回一個中間件,使用這個中間件會讓上下文獲得一個渲染方法;
  2. 從渲染方法參數(shù)上獲取傳遞的數(shù)據(jù)(其次從 ctx.state 獲取),然后使用 nunjucks 渲染模板;
  3. 根據(jù)用戶配置決定是否返回HTML頁面。

可以參考從源碼里面截取的片段,如下:

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();
  };

從上面的代碼可以看出,在創(chuàng)建 koa-nunjucks-2 中間件時,可以傳遞文件后綴 ext ,渲染方法名 functionName ,以及 nunjucks 的配置信息 nunjucksConfig 等。

基本配置

創(chuàng)建Koa應(yīng)用

下面的代碼創(chuàng)建了一個koa web服務(wù),監(jiān)聽了3000端口,如果訪問 http://localhost:3000/ 將返回 Not Found ,這是因為代碼沒有對請求做任何響應(yīng)。后面將使用 koa-nunjucks-2 在這個基礎(chǔ)上進行修改,使其支持渲染頁面。

// app.js

const Koa = require('koa'); // 引入koa

const app = new Koa(); // 創(chuàng)建koa應(yīng)用

// 啟動服務(wù)監(jiān)聽本地3000端口
app.listen(3000, () => {
    console.log('應(yīng)用已經(jīng)啟動,http://localhost:3000');
})

安裝 koa-nunjucks-2

$ npm install koa-nunjucks-2 --save

使用 koa-nunjucks-2

首先,使用 require() 引入 koa-nunjucks-2 ,并且對其實例化(支持傳遞參數(shù)),然后會獲得一個中間件。并且調(diào)用 app.use() 使用這個中間件:

const Koa = require('koa'); // 引入koa
const koaNunjucks = require('koa-nunjucks-2'); // 引入 koa-nunjucks-2
const path = require('path');

const app = new Koa(); // 創(chuàng)建koa應(yīng)用

// 使用 koa-nunjucks-2 實例獲得中間件
app.use(koaNunjucks({
    ext: 'html', // 使用HTML后綴的模板
    path: path.join(__dirname, 'view'), // 模板所在路徑
    nunjucksConfig: { // nunjucks的配置
        trimBlocks: true
    }
}));

// 啟動服務(wù)監(jiān)聽本地3000端口
app.listen(3000, () => {
    console.log('應(yīng)用已經(jīng)啟動,http://localhost:3000');
})

配置好 koa-nunjucks-2 中間件之后,它默認(rèn)會在請求上下文(context)上增加 render() 方法,通過調(diào)用 ctx.render('模板名', 數(shù)據(jù)) 就可以渲染頁面,比如下面代碼:

// app.js

const Koa = require('koa'); // 引入koa
const koaNunjucks = require('koa-nunjucks-2'); // 引入 koa-nunjucks-2
const path = require('path');

const app = new Koa(); // 創(chuàng)建koa應(yīng)用

// 使用 koa-nunjucks-2 實例獲得中間件
app.use(koaNunjucks({
    ext: 'html', // 使用HTML后綴的模板
    path: path.join(__dirname, 'view'), // 模板所在路徑
    nunjucksConfig: { // nunjucks的配置
        trimBlocks: true
    }
}));

+ app.use(async ctx => {
+     await ctx.render('index', { text: 'Hello World!' }); // 使用 ctx.render 可以通過 + nunjucks 渲染頁面
+ })

// 啟動服務(wù)監(jiān)聽本地3000端口
app.listen(3000, () => {
    console.log('應(yīng)用已經(jīng)啟動,http://localhost:3000');
})

模板里面的代碼如下:

<!-- view/index.html -->

<h1>
    {{ text }}
</h1>

在調(diào)用 ctx.render 時傳遞的數(shù)據(jù)可以在模板里面通過插值表達(dá)式的形式 {{ text }} 渲染出來,可以訪問 http://localhost:3000/ 進行確認(rèn)。

配合 koa-router 使用

關(guān)于 koa-router 的使用可以參考這里:Koa中間件使用之koa-router ,這里使用 koa-router 來匹配路徑,從而達(dá)到渲染不同頁面的目的。

先來在代碼里面加入 koa-router

// app.js

// ...
+ const Router = require('koa-router');

const app = new Koa(); // 創(chuàng)建koa應(yīng)用
+ const router = new Router();

// 使用 koa-nunjucks-2 實例獲得中間件
app.use(koaNunjucks({
    ext: 'html', // 使用HTML后綴的模板
    path: path.join(__dirname, 'view'), // 模板所在路徑
    nunjucksConfig: { // nunjucks的配置
        trimBlocks: true
    }
}));

- app.use(async ctx => {
+ router.get('/', async ctx => {
    await ctx.render('index', { text: 'Hello World!' }); // 使用 ctx.render 可以通過 nunjucks 渲染頁面
})

+ app.use(router.routes()).use(router.allowedMethods());

// 啟動服務(wù)監(jiān)聽本地3000端口
app.listen(3000, () => {
    console.log('應(yīng)用已經(jīng)啟動,http://localhost:3000');
})

上面的代碼中, app.use(nunjucks({})) 放在 app.use(router.routes()).use(router.allowedMethods()) 前面才行,否則會報 ctx.render() 不是一個 function 。

Nunjucks使用

這里指列舉一些使用方法,具體可以參考 nunjucks 的文檔 。

變量

變量會從模板上下文獲取,如果你想顯示一個變量可以:

{{ username }}

會從上下文查找 username 然后顯示,可以像 javascript 一樣獲取變量的屬性:

{{ foo.bar }}
{{ foo["bar"] }}

過濾器

過濾器是一些可以執(zhí)行變量的函數(shù),通過管道操作符 (|) 調(diào)用,并可接受參數(shù)。

{{ foo | title }}
{{ foo | join(",") }}
{{ foo | replace("foo", "bar") | capitalize }}

第三個例子展示了鏈?zhǔn)竭^濾器,最終會顯示 "Bar",第一個過濾器將 "foo" 替換成 "bar",第二個過濾器將首字母大寫。

Nunjucks 提供了一些內(nèi)置的過濾器,你也可以自定義過濾器

if

if 為分支語句,與 javascript 中的 if 類似。

{% if variable %}
  It is true
{% endif %}

如果 variable 定義了并且為真值。

{% if hungry %}
  I am hungry
{% elif tired %}
  I am tired
{% else %}
  I am good!
{% endif %}

for

for 可以遍歷數(shù)組 (arrays) 和對象 (dictionaries)。

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>

更多的使用這里不再列舉,可以查看官方的文檔。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容