iT邦幫忙

DAY 26
5

node.js伺服器實戰系列 第 26

node.js伺服器實戰(26) - 整合模板引擎

昨天只是簡單地驗證概念,今天先拿一個template引擎來測試一下。
swig模版引擎

swig是可以在node.js中運行的一個template引擎,他的速度相當快,而且功能也相當豐富,所以先拿它來測試一下。

swig的官網:
http://paularmstrong.github.com/swig/

線上說明:
https://github.com/paularmstrong/swig/tree/master/docs

文件是用markdown格式,雖然是放在github repository中,但是可以在線上直接瀏覽。

swig的使用很簡單,初始化之後,可以利用compileFile(filename)或是compile(string)兩個方法編譯template,這兩個方法會回傳編譯好的template物件,呼叫他的render(data obj)方法就可以產出結果。

template語法也很簡單,使用{{name}}就可以把透過render(data)傳入的物件的data.name引入。一些邏輯結構或判斷可以用內建的tag來做,例如{%for row in rows%},會處理data.rows陣列中的每一個元素,把它引入到從tag開始到{%endfor%}為止的內容中,變數名稱是{{row}}。

假設有一個template:

 <title>{{title}}</title>
 
 <table border="1" cellspacing="0" cellpadding="2">
 {%for row in rows%}
 <tr><td>{{row.name}}</td><td>{{row.email}}</td></tr>
 {%endfor%}
 </table>
 
 

然後render時使用的物件是:

 {
     title: 'swig template test', 
     rows: [
         {name: 'test name1', email: 'name1@email.com'},
         {name: 'test name2', email: 'name2@email.com'}
     ]
 }

最後render的產出:

 <title>swig template test</title>
 
 <table border="1" cellspacing="0" cellpadding="2">
 
 <tr><td>test name1</td><td>name1@email.com</td></tr>
 
 <tr><td>test name2</td><td>name2@email.com</td></tr>
 
 </table>
 
 

在route handler中使用swig

把昨天寫的程式稍微調整一下,就可以使用swig了。首先是views.js:

 var swig = require('swig');
 
 swig.init({
     allowErrors: false,
     autoescape: true,
     encoding: 'utf8',
     filters: {},
     root: '.',
     tags: {}
 });
 
 module.exports = {
     "hello_mvc": function(cb) {
         var view = swig.compileFile('tests/temp1.html');
         this.render = function(data) {
             cb(false, '/hello_mvc', {type:'text/html', data: view.render(data)});
         };
     }
 };

models.js中的資料也需要稍微調整:

 module.exports = {
     "hello_mvc": function(view) {
         var data = {
             title: 'test swig template',
             rows: [
                 {name: 'test name 1', email: 'name1@email.com'},
                 {name: 'test name 2', email: 'name2@email.com'}
             ]
         };
         this.execute = function() {
             process.nextTick(function() {
                 view.render(data);
             });
         }
     }
 };

最後需要調整整合測試檔,setUp的部份:

        .get('/hello_mvc', function (request, response, cb) {
            var HelloModel = require('./models')['hello_mvc'];
            var HelloView = require('./views')['hello_mvc'];
            var m = new HelloModel(new HelloView(cb));
            m.execute();
        });

這部份沒有邏輯的變動,只是把測試資料以及views.js還有models.js移到tests資料夾中,並且調整名稱。實際做assertion的部份:

    "test router hello_mvc": function(test) {
        test.expect(6);
        var req = this.http.request({
            "host": "localhost",
            "port": 8443,
            "path": "/hello_mvc",
            "method": "GET"
        }, function(response) {
            var result = [];
            response.on('data', function(data) {
                result.push(data);
            });
            response.on('end', function() {
                var total = 0;
                var entity = '';
                for(var i=0; i<result.length; i++) {
                   total += result[i].length;
                   entity += result[i].toString('utf8');
                }
                test.equal(200, response.statusCode);
                test.ok(entity.indexOf('test swig template')>-1);
                test.ok(entity.indexOf('test name 1')>-1);
                test.ok(entity.indexOf('test name 2')>-1);
                test.ok(entity.indexOf('name1@email.com')>-1);
                test.ok(entity.indexOf('name2@email.com')>-1);
                test.done();
            });
        });
        req.end();
    }

因為輸出結果更複雜,所以用個多條件來做驗證。

接下來用ant integrate做一下整合測試來看看結果:

 Feng-Hsu-Pingteki-MacBook-Air:evolve fillano$ ant integrate
 Buildfile: /Users/fillano/Dropbox/shared/evolve/build.xml
 
 clear-lib-cov:
 
 coverage-init:
 
 integrate:
......
      [exec] 3704::7: 6718720
      [exec] 3704::/hello_mvc exists.
      [exec] ok: test router hello_mvc
......
      [exec] 
      [exec] OK: 20 assertions (229ms)
 
 BUILD SUCCESSFUL
 Total time: 2 seconds

OK,看起來整合其他的template引擎,這樣做也沒問題。接下來就要再看看model的部份了。

今天的範例檔fillano-evolve-v0.0.19-0-g74a4bbb.zip,目前版本是v0.0.19。

相關文章


上一篇
node.js伺服器實戰(25) - 初步設計視圖與模型的互動方式
下一篇
node.js伺服器實戰(27) - 整合資料庫引擎
系列文
node.js伺服器實戰33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言