Template engine是什麼
模板引擎幫助我們在靜態的html檔案中插入一些動態的變數,使頁面的呈現可以實際與資料互動。模板引擎可以讓介面與資料分離,提升開發的效率使分工更明確,還可以減少重複程式碼的產生。
經過模板引擎的編譯,最終會回傳一般的html檔案到用戶端。
使用template engine渲染html
利用express來設定template engine
express提供我們設定專案所使用的模板引擎,省去我們自行設定模板引擎的作業,減少開發者撰寫程式碼的負擔
首先必須安裝模板引擎到專案中,以pug
為例 (模板引擎有很多種,需自行分析優缺點選擇喜歡的模板引擎)npm install --save pug
安裝好後在app.js設定使用的模板引擎,新增app.set('view engine', 'pug');
到該檔中app.use()
可以讓我們設定global變數到express的application中 (name: value),其中有些name
是用來改變server的行為的,有哪些特殊的name
可以參考文件
因此我們設定view engine
這個特殊的name
為pug
,告訴express接下來這個專案會使用pug
作為模板引擎而不是其他的模板引擎。
設定模板引擎的種類後,還必須告訴express必須渲染的動態檔案 (ex. index.pug)放在哪個資料夾
所以再加入以下這行app.set('views', 'views')
後面的views
為檔案夾名稱 (預設其實已經是views,但可以根據自己檔案夾命名更改),這樣一來express就知道該去哪裡找這些檔案,之後將原本撰寫html的方式改為pug的特殊語法,副檔名也必須是.pug
根據不同的engine可能需要在程式碼中使用require()
引入,例如pug不用但handlebars要
handlebars的情況下要加這兩行
1 | const expressHbs = require('express-handlebars'); |
實際渲染.pug檔產生html給用戶端
還有最後一步,原本使用res.sendFile()
來回傳html檔案給前端,使用模板引擎後必須改為以下res.render()
所以在我們處理routes的檔案中會變成
shop.js
1 | const path = require('path'); |
這裡res.render()
裡面不需要包含完整的路徑是因為express已經知道該去哪裡找這些檔案 (views),且也已經知道使用的模板引擎種類所以可以省略副檔名.pug
Html語法轉Pug語法
pug的撰寫方式與html非常相像,遵循一定的規則就可以輕鬆改寫。pug語法多了一些邏輯判斷和迴圈幫助減少重複程式碼的撰寫,以及pug可以插入變數,根據變數渲染網頁達到動態的效果。
pug語法重視縮排,如果一個標籤被上層的標籤包住,必須往內縮一排
pug語法不需要結尾標籤
範例如下
1 | <header class="main-header"> |
轉換成pug語法後
1 | header.main-header |
改變一下標籤, class, 屬性的表示方法
如果要在pug使用動態變數,首先要在渲染pug檔指定加上需要傳遞的變數,如下
shop.js
1 | router.get('/', (req, res, next) => { |
res.render()
的第二個變數傳遞一個物件結構,使用key value來傳遞
接著在pug檔使用以下方式插入變數
1 | if prods.length > 0 |
共同Layout
在很多時候不同的頁面會有相同的設計,例如每個頁面都有一個導覽列,這樣的話會有同樣的代碼重複在不同的檔案。這時候可以使用pug創造一個共同的layout,每個頁面都可以引入這個layout再根據各自需求去修改它
首先可以在views
資料夾再創個layouts
資料夾,再新增一個pug檔
main-layout.pug
1 | <!DOCTYPE html> |
透過在layout中安插佔位空間(placeholder)來提供客製化的空間,例如代碼中block styles
block content
的部分,這裡被其他pug檔引入後可以做各自的修改
也可以根據條件加入不同的css classa(href="/admin/add-product", class=(path === '/admin/add-product' ? 'active' : ''))
add-products.pug
1 | extends layouts/main-layout.pug |