模板入門

模板是一個文字檔案,定義了輸出檔案的結構或佈局,並使用佔位符表示在渲染模板時(在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 子目錄中搜索模板。

js
// 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 元素內部,等等。非巢狀元素(例如,單個段落)位於單獨的行上。

pug
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 程式碼等效項,如 &gt;),以防止 JavaScript 注入或跨站點指令碼攻擊。

如果標籤後跟等號,則後續文字將被視為 JavaScript 表示式。例如,在下面的第一行中,h1 標籤的內容將是 變數 title(在檔案中定義或從 Express 傳遞到模板中)。在第二行中,段落內容是一個文字字串與 title 變數連線在一起。在這兩種情況下,預設行為都是 轉義該行。

pug
h1= title
p= 'Evaluated and <em>escaped expression</em>:' + title

注意:在 Pug 模板中,使用但未從 Express 程式碼(或本地定義)中傳遞的變數為“未定義”。如果你在沒有傳遞 title 變數的情況下使用此模板,則會建立標籤,但它們將包含空字串。如果在條件語句中使用未定義的變數,則它們將計算為 false。其他模板語言可能要求在模板中使用的變數必須定義。

如果標籤後面沒有等號,則內容將被視為純文字。在純文字中,你可以分別使用 #{}!{} 語法插入轉義和未轉義的資料,如下所示。你也可以在純文字中新增原始 HTML。

pug
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}.

注意:你幾乎總是希望轉義來自使用者的(透過 #{} 語法)資料。可以信任的資料(例如,生成的記錄計數等)可以在不轉義值的情況下顯示。

你可以在一行的開頭使用管道 ('|') 字元來指示“純文字”。例如,下面顯示的附加文字將顯示在前面錨點的同一行上,但不會連結。

pug
a(href='http://someurl/') Link text
| Plain text

Pug 允許你使用 ifelseelse ifunless 執行條件操作——例如

pug
if title
  p A variable named "title" exists
else
  p A variable named "title" does not exist

你還可以使用 each-inwhile 語法執行迴圈/迭代操作。在下面的程式碼片段中,我們迴圈遍歷了一個數組以顯示變數列表(請注意,下面使用 'li=' 將“val”計算為變數。你迭代的值也可以作為變數傳遞到模板中!

pug
ul
  each val in [1, 2, 3, 4, 5]
    li= val

語法還支援註釋(可以根據你的選擇在輸出中渲染——或不渲染——),mixin 用於建立可重用的程式碼塊,case 語句以及許多其他功能。有關更詳細的資訊,請參閱 Pug 文件

擴充套件模板

在整個站點中,所有頁面通常都具有共同的結構,包括頭部、頁尾、導航等的標準 HTML 標記。為了避免開發人員在每個頁面中重複此“樣板程式碼”,Pug 允許你宣告一個基本模板,然後擴充套件它,只替換每個特定頁面中不同的部分。

例如,在我們的 框架專案 中建立的基本模板 layout.pug 如下所示

pug
doctype html
html
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
  body
    block content

block 標籤用於標記可以在派生模板中替換的內容部分(如果未重新定義塊,則使用基類中的實現)。

預設的 index.pug(為我們的框架專案建立)顯示了我們如何覆蓋基本模板。extends 標籤標識要使用的基本模板,然後我們使用 block section_name 來指示我們將覆蓋的部分的新內容。

pug
extends layout

block content
  h1= title
  p Welcome to #{title}

後續步驟