Express支持許多模板引擎,常用的有:
視圖的文件名默認需遵循“<name>.<engine>”的形式,這裡<engine>是要被加載的模塊的名字。比如視圖layout.ejs就是在告訴視圖系統要require(‘ejs'),被加載的模塊必須輸出exports.compile(str, options)方法,並要返回一個函數來遵守Express的模板接口約定。我們也可以使用app.register()來映射模板引擎到其它文件擴展名,從而實現更靈活的模板引擎行為,如此一來就可以實現“csser.html”可以被ejs引擎所渲染。
下面我們將用Jade引擎來渲染index.html,因為我們沒有設置layout:false,index.jade渲染後的內容將被作為body本地變量傳入layout.jade。
復制代碼 代碼如下:
<SPAN style="FONT-SIZE: 13px">app.get('/', function(req, res){
res.render('index.jade', { title: 'CSSer, 關注Web前端技術!' });
});
</SPAN>
新增的“view engine”設置可以指定默認模板引擎,如果我們想使用jade可以這樣設置:
復制代碼 代碼如下:
<SPAN style="FONT-SIZE: 13px">app.set('view engine', 'jade');
</SPAN>
於是我們就可以通過下面的方式:
復制代碼 代碼如下:<SPAN style="FONT-SIZE: 13px">res.render('index');
</SPAN>
代替如下方式:
復制代碼 代碼如下:<SPAN style="FONT-SIZE: 13px">res.render('index.jade');
</SPAN>
當“view engine”設置後,模板的擴展名就成了可選項,同時我們還可以混合匹配多模板引擎:
復制代碼 代碼如下:<SPAN style="FONT-SIZE: 13px">res.render('another-page.ejs');
</SPAN>
Express同時提供了視圖選項設置,這些設置會在每次視圖渲染後應用,比如你並不經常使用layouts,就可以這樣設置:
復制代碼 代碼如下:<SPAN style="FONT-SIZE: 13px">app.set('view options', {
layout: false
});
</SPAN>
如果需要,這些設置可以在後續的res.render()調用中被覆蓋:
復制代碼 代碼如下:<SPAN style="FONT-SIZE: 13px">res.render('csser-view.ejs', { layout: true });
</SPAN>
可以通過指定一個路徑的方式來實現用自己的layout來代替系統默認的,比如如果我們將“view engine”設置為jade並且自定義了一個名為“./views/mylayout.jade”的layout,我們可以這樣使用它:
復制代碼 代碼如下:<SPAN style="FONT-SIZE: 13px">res.render('page', { layout: 'mylayout' });
</SPAN>
否則必須指定擴展名:
復制代碼 代碼如下:<SPAN style="FONT-SIZE: 13px">res.render('page', { layout: 'mylayout.jade' });
</SPAN>
這些路徑也可以是絕對路徑:
復制代碼 代碼如下:<SPAN style="FONT-SIZE: 13px">res.render('page', { layout: __dirname + '/http://www.jb51.net/mylayout.jade' });
</SPAN>
這方面較好的例子就是自定義ejs模板的開始和關閉的標記:
復制代碼 代碼如下:<SPAN style="FONT-SIZE: 13px">app.set('view options', {
open: '{{',
close: '}}'
});
</SPAN>
局部視圖(View Partials)
Express視圖系統原生支持局部和集合視圖,這稱作微型視圖,主要用於渲染一個文檔片段。比如與其在視圖中循環顯示評論,不如使用局部集合(partial collection):
復制代碼 代碼如下:<SPAN style="FONT-SIZE: 13px">partial('comment', { collection: comments });
</SPAN>
如果不需要其它選項或本地變量,我們可以省略對象而簡單的傳入評論數組,這和上面的示例是一樣的:
復制代碼 代碼如下:<SPAN style="FONT-SIZE: 13px">partial('comment', comments);
</SPAN>
當使用局部集合時,支持一些“魔術”本地變量:
Local variables passed (or generated) take precedence, however locals passed to the parent view are available in the child view as well. So for example if we were to render a blog post with partial(‘blog/post', post) it would generate the post local, but the view calling this function had the local user, it would be available to the blog/post view as well.
傳入(或生成)的本地變量優先,但傳入父視圖的本地變量在子視圖仍有效。因此如果我們用partial(‘blog/post', post)來渲染博客日志時,將生成post的本地變量,但調用本函數的視圖擁有本地用戶,它在blog/post視圖依然有效。(一回注:這段翻譯感覺有問題,請高人指點)。
性能提示:當使用局部集合渲染100長度的數組就意味著需要渲染100次視圖,對於簡單的集合你可以將循環內聯,而不要使用局部集合,這樣可以減少系統開銷。
視圖查找是相對於父視圖進行的,比如我們有一個名為“views/user/list.jade”的頁面視圖,如果在該視圖中調用 partial(‘edit'),視圖系統將會嘗試查找並加載“views/user/edit.jade”,而partial(‘.. /messages')將加載“views/messages.jade”。
視圖系統還支持索引模板,這樣你就可以使用一個同名的目錄。比如,在一個路由中我們執行res.render(‘users'),這將指向“views/users.jade”或者“views/users/index.jade”。
當使用上面的索引視圖時,我們可以通過partial(‘users')從同名目錄下引用“views/users/index.jade”,同時視圖系統會嘗試“../users/index”,這能減少我們調用partial(‘index')的需要。