模板入門
模板是定義輸出檔案結構或佈局的文字檔案,其中包含佔位符,用於表示模板渲染時(在 Express 中,模板被稱為檢視)資料將被插入的位置。
Express 模板選擇
Express 可以與許多不同的模板渲染引擎一起使用。在本教程中,我們使用 Pug(以前稱為 Jade)作為模板。它是最流行的 Node 模板語言,自稱是一種“乾淨、對空白敏感的 HTML 編寫語法,深受 Haml 影響”。
不同的模板語言使用不同的方法來定義佈局和標記資料佔位符——有些使用 HTML 定義佈局,而另一些則使用可以轉換成 HTML 的不同標記格式。Pug 屬於第二種;它使用 HTML 的一種表示形式,其中每行的第一個詞通常代表一個 HTML 元素,後續行的縮排用於表示巢狀。其結果是一個直接轉換為 HTML 的頁面定義,但更簡潔,並且可以說更易於閱讀。
注意:使用 Pug 的一個缺點是它對縮排和空白敏感(如果你在錯誤的地方新增額外的空格,你可能會得到一個無用的錯誤程式碼)。然而,一旦你的模板就位,它們就非常容易閱讀和維護。
模板配置
當我們在建立骨架網站時,LocalLibrary 被配置為使用 Pug。你應該會在網站的 package.json 檔案中看到 pug 模組作為依賴項包含在內,以及在 app.js 檔案中看到以下配置設定。這些設定告訴我們正在使用 pug 作為檢視引擎,並且 Express 應該在 /views 子目錄中搜索模板。
// View engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "pug");
如果你檢視 views 目錄,你會看到專案預設檢視的 .pug 檔案。這些檔案包括主頁檢視 (index.pug) 和我們稍後需要用自己的內容替換的基礎模板 (layout.pug)。
/express-locallibrary-tutorial # the project root
/views
error.pug
index.pug
layout.pug
模板語法
下面的示例模板檔案展示了 Pug 許多最有用的功能。
首先要注意的是,該檔案映射了典型 HTML 檔案的結構,每行(幾乎)的第一個詞都是一個 HTML 元素,並且縮排用於表示巢狀元素。例如,body 元素位於 html 元素內部,段落元素 (p) 位於 body 元素內部,依此類推。非巢狀元素(例如,單獨的段落)位於單獨的行上。
doctype html
html(lang="en")
head
title= title
script(type='text/javascript').
body
h1= title
p This is a line with #[em some emphasis] and #[strong strong text] markup.
p This line has un-escaped data: !{'<em> is emphasized</em>'} and escaped data: #{'<em> is not emphasized</em>'}.
| This line follows on.
p= 'Evaluated and <em>escaped expression</em>:' + title
<!-- You can add HTML comments directly -->
// You can add single line JavaScript comments and they are generated to HTML comments
//- Introducing a single line JavaScript comment with "//-" ensures the comment isn't rendered to HTML
p A line with a link
a(href='/catalog/authors') Some link text
| and some extra text.
#container.col
if title
p A variable named "title" exists.
else
p A variable named "title" does not exist.
p.
Pug is a terse and simple template language with a
strong focus on performance and powerful features.
h2 Generate a list
ul
each val in [1, 2, 3, 4, 5]
li= val
元素屬性在其關聯元素後的括號中定義。在括號內,屬性以逗號或空格分隔的屬性名稱和屬性值對的列表形式定義,例如
script(type='text/javascript'),link(rel='stylesheet', href='/stylesheets/style.css')meta(name='viewport' content='width=device-width initial-scale=1')
所有屬性的值都經過轉義(例如,> 這樣的字元被轉換為其 HTML 程式碼等效項,例如 >),以防止 JavaScript 注入或跨站指令碼攻擊。
如果標籤後跟等號,則後續文字將被視為 JavaScript 表示式。因此,例如,在下面的第一行中,h1 標籤的內容將是變數 title(在檔案中定義或從 Express 傳遞到模板中)。在第二行中,段落內容是與 title 變數連線的文字字串。在這兩種情況下,預設行為都是轉義該行。
h1= title
p= 'Evaluated and <em>escaped expression</em>:' + title
注意:在 Pug 模板中,如果一個變數被使用但沒有從你的 Express 程式碼中傳入(或在本地定義),那麼它就是“未定義的”。如果你在沒有傳入 title 變數的情況下使用此模板,則會建立標籤,但它們將包含一個空字串。如果你在條件語句中使用未定義變數,則它們會評估為 false。其他模板語言可能要求模板中使用的變數必須被定義。
如果標籤後沒有等號,則內容被視為純文字。在純文字中,你可以分別使用 #{} 和 !{} 語法插入轉義和非轉義資料,如下所示。你還可以在純文字中新增原始 HTML。
p This is a line with #[em some emphasis] and #[strong strong text] markup.
p This line has an un-escaped string: !{'<em> is emphasized</em>'}, an escaped string: #{'<em> is not emphasized</em>'}, and escaped variables: #{title}.
注意:你幾乎總是希望轉義來自使用者的資料(透過 #{} 語法)。可以信任的資料(例如,生成的記錄計數等)可以在不轉義值的情況下顯示。
你可以在行首使用管道字元('|')來表示“純文字”。例如,下面顯示的額外文字將顯示在與前一個錨點相同的行上,但不會被連結。
a(href='http://someurl/') Link text
| Plain text
Pug 允許你使用 if、else、else if 和 unless 執行條件操作——例如
if title
p A variable named "title" exists
else
p A variable named "title" does not exist
你還可以使用 each-in 或 while 語法執行迴圈/迭代操作。在下面的程式碼片段中,我們迴圈遍歷一個數組以顯示變數列表(請注意下面使用 'li=' 將“val”評估為變數。你迭代的值也可以作為變數傳遞到模板中!
ul
each val in [1, 2, 3, 4, 5]
li= val
該語法還支援註釋(可以渲染在輸出中,也可以不渲染——由你選擇)、混合(用於建立可重用程式碼塊)、case 語句和許多其他功能。有關更詳細的資訊,請參閱 Pug 文件。
擴充套件模板
在一個網站中,所有頁面通常具有共同的結構,包括用於頭部、頁尾、導航等的標準 HTML 標記。Pug 不會強制開發人員在每個頁面中重複這些“樣板”程式碼,而是允許你宣告一個基礎模板,然後對其進行擴充套件,只替換每個特定頁面中不同的部分。
例如,在我們的骨架專案中建立的基礎模板 layout.pug 如下所示
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content
block 標籤用於標記在派生模板中可能被替換的內容部分(如果塊未重新定義,則使用其在基類中的實現)。
預設的 index.pug(為我們的骨架專案建立)展示了我們如何覆蓋基礎模板。extends 標籤標識要使用的基礎模板,然後我們使用 block section_name 來指示我們將覆蓋的部分的新內容。
extends layout
block content
h1= title
p Welcome to #{title}
後續步驟
- 返回 Express 教程第 5 部分:顯示圖書館資料。
- 繼續閱讀第 5 部分的下一子文章:LocalLibrary 基礎模板。