JavaScript >> Javascript 文檔 >  >> Node.js

致嘗試使用 Jade 模板引擎卻無法上手的工程師

當我開始在 Storify 擔任 Node.js 工程師時。技術棧是 Express 和 Jade。我不想承認,但我和 Jade 很掙扎!

之前,我主要使用 Underscore 和 Handlebars。我試圖在 Jade 模板中修改一些 HTML。其他時候我只會更改文本。這些都是微不足道的更新,但通常它們會導致整個服務器崩潰 .

我慘遭失敗,無法通過反複試驗來學習。我討厭傑德。我也開始討厭編輯模板。然後我有一個燈泡時刻:我需要一個教程。我去了官方文檔。我希望這篇文章當時存在。只花了一個小時學習 Jade,我就可以使用 Jade 並順利地對模板進行所有更改。

聰明的人從錯誤中學習,聰明的人從別人身上學習 .不要重複我的愚蠢行為。瀏覽這個 Jade 教程,利用這種美妙的模板語言的力量。

模板引擎是使用某些規則/語言來解釋數據和呈現視圖的庫或框架。對於 Web 應用程序,視圖是 HTML 頁面(或其中的一部分),但它們可以是 JSON 或 XML 文件,或者在桌面程序中是 GUI。對於熟悉模型-視圖-控制器概念的人來說,模板屬於視圖。

在 Web 應用程序中,使用模板是有益的,因為我們可以使用單個模板動態生成無限數量的頁面!另一個好處是當我們需要改變某些東西時;我們只能在一個地方完成。

如果我們回到上一章中的圖表(傳統與 REST API 方法),我們可以推斷模板可以在服務器端(傳統方法)或客戶端(REST API 方法)編譯成 HTML。無論我們採用哪種方法,庫本身的語法都保持不變。

在本文中,我將介紹以下內容:

  • Jade 語法和功能
  • Jade 獨立使用

Jade 語法和功能

Jade 是 Haml 的 Node.js 兄弟,因為它使用空格和縮進作為其語言的一部分。因此,我們需要注意遵循正確的語法。

您可以在線、在官方網站的演示頁面 (http://jade-lang.com/demo) 或 @naltatis 資源 (http://naltatis.github.io/) 上遵循本節中的 Jade 語法示例jade-syntax-docs/),或者通過編寫獨立的 Node.js 腳本(示例在本章後面的“Jade Standalone Usage”中提供)。

標籤

行首的任何文本(默認情況下)都被解釋為 HTML 標記。 Jade 的主要優點是該文本呈現 HTML 元素的結束標籤和開始標籤,以及 <></> 符號。因此,我們為使用 Jade 編寫的開發人員節省了許多擊鍵!

標記和空格後面的文本(例如,tag <text> ) 被解析為內部 HTML(即元素內的內容)。例如,如果我們有以下 Jade 代碼:

Body
  div
    h1 Practical Node.js
    p The only book most people will ever need.
  div
    footer &copy; Apress

上面模板的輸出將是:

<body>
  <div>
    <h1>Practical Node.js</h1>
    <p>The only book most people will ever need.</p>
  </div>
  <div>
    <footer>&copy; Apress</footer>
  </div>
</body>

變量/局部變量

傳遞給 Jade 模板的數據稱為 locals .要輸出變量的值,請使用 = .請看以下示例:

[旁注]

閱讀博客文章很好,但觀看視頻課程更好,因為它們更具吸引力。

許多開發人員抱怨 Node.js 上缺乏負擔得起的高質量視頻材料。觀看 YouTube 視頻會讓人分心,花 500 美元購買 Node 視頻課程很瘋狂!

去看看 Node University,它有關於 Node 的免費視頻課程:node.university。

[旁注結束]

玉碼:

h1= title
p= body

當地人:

{
  title: "Express.js Guide",
  body: "The Comprehensive Book on Express.js"
}

HTML 輸出:

<h1>Express.js Guide</h1>
<p>The Comprehensive Book on Express.js</p> 

屬性

通過將屬性放在標籤名稱後面的括號中來添加屬性。他們遵循 name=value 格式。另外,多個屬性需要用逗號分隔。例如,

div(id="content", class="main")
  a(href="http://expressjsguide.com", title="Express.js Guide", target="_blank") Express.js Guide
  form(action="/login")
    button(type="submit, value="save")
div(class="hero-unit") Lean Node.js!

變成:

<div id="content" class="main"><a href="http://expressjsguide.com" title="Express.js Guide"
target="_blank">Express.js Guide</a>
  <form action="/login">
    <button type="submit" value="save"></button>
  </form>
  <div class="hero-unit">Learn Node.js</div>
</div>

有時,屬性的值需要是動態的。在這種情況下,只需使用變量名!管道,或 | , 允許我們在新行上寫入 HTML 節點的內容——換句話說,帶有管道的行變成了內部文本,示例如下:

a(href=url, data-active=isActive)
label
  input(type="checkbox", checked=isChecked)
  | yes / no

上面的模板是本地提供的:

{
  url: "/logout",
  isActive: true,
  isChecked: false
}

它們都產生輸出,即模板和本地數據:

<a href="/logout" data-active="data-active"></a>
<label>
  <input type="checkbox"/>yes / no
</label>

請注意,值為 false 的屬性 從 HTML 輸出中省略。但是,當沒有傳遞任何值時,true 假設——例如:

input(type='radio', checked)
input(type='radio', checked=true)
input(type='radio', checked=false)
<input type="radio" checked="checked"/>
<input type="radio" checked="checked"/>
<input type="radio"/>

文字

為方便起見,我們可以在標籤名稱之後寫下類和 ID。例如,我們可以應用 leadcenter 類到一個段落,並創建一個 div side-bar 元素 ID 和 pull-right 類(同樣,管道表示內部文本):

div#content
  p.lead.center
    | webapplog: where code lives
    #side-bar.pull-right
    span.contact.span4
      a(href="/contact") contact us
<div id="content">
  <p class="lead center">
    webapplog: where code lives
    <div id="side-bar" class="pull-right"></div>
    <span class="contact span4">
      <a href="/contact">contact us</a>
    </span>
  </p>
</div>

注意如果省略標籤名,div 改為使用。

文字

通過 | 輸出原始文本——例如:

div
  | Jade is a template engine.
  | It can be used in Node.js and in the browser JavaScript.

腳本和样式塊

有時,開發人員希望為 script 編寫大量內容 或 style HTML 中的標籤!這可以通過一個點來實現。例如,我們可以這樣編寫內聯前端 JavaScript:

script.
   console.log('Hello Jade!')
   setTimeout(function(){
    window.location.href='http://rpjs.co'
   },200))
   console.log('Good bye!')
<script>
  console.log('Hello Jade!')
  setTimeout(function(){
   window.location.href='http://rpjs.co'
  },200))
  console.log('Good bye!')
</script> 

JavaScript 代碼

與前面的例子相反,如果我們想使用 any 模板編譯時的 Ja​​vaScript——換句話說,要編寫可執行的 JavaScript 代碼來操作 Jade 的輸出(即 HTML)——我們可以使用 - , = , 或 != 符號。當我們輸出 HTML 元素並註入 JavaScript 時,這可能會派上用場。顯然,這些類型的事情應該小心完成以避免跨站點腳本 (XSS) 攻擊。比如我們要定義一個數組,輸出<> 符號,我們可以使用 != .

- var arr = ['<a>','<b>','<c>']
ul
  - for (var i = 0; i< arr.length; i++)
    li
      span= i
      span!="unescaped: " + arr[i] + " vs. "
      span= "escaped: " + arr[i]

產生這個:

<ul>
  <li><span>0</span><span>unescaped: <a> vs. </span><span>escaped: &lt;a&gt;</span></li>
  <li><span>1</span><span>unescaped: <b> vs. </span><span>escaped: &lt;b&gt;</span></li>
  <li><span>2</span><span>unescaped: <c> vs. </span><span>escaped: &lt;c&gt;</span></li>
</ul>

提示 Jade 和 Handlebars 之間的主要區別之一是前者允許在其代碼中使用幾乎任何 JavaScript,而後者將程序員限制為只有少數內置和自定義註冊的幫助程序。

評論

當涉及到評論時,我們可以選擇是否輸出它們。對於前者,使用 JavaScript 樣式 //; 對於後者,使用 //- .例如,

// content goes here
p Node.js is a non-blocking I/O for scalable apps.
//- @todo change this to a class
p(id="footer") Copyright 2014 Azat

輸出:

<!-- content goes here-->
<p>Node.js is a non-blocking I/O for scalable apps.</p>
<p id="footer">Copyright 2014 Azat</p>

條件(如果)

有趣的是,除了標準的 JavaScript 代碼,if 語句可以通過在它前面加上 - 來使用 ,我們可以使用沒有前綴和括號的簡約 Jade 替代方案——例如:

- var user = {}
- user.admin = Math.random()>0.5
if user.admin
    button(class="launch") Launch Spacecraft
else
    button(class="login") Log in

還有unless,相當於not! .

迭代(每個循環)

與條件類似,Jade 中的迭代器可以簡單地用 each— 編寫 例如:

- var languages = ['php', 'node', 'ruby']
div
  each value, index in languages
    p= index + ". " + value

HTML輸出如下:

<div>
  <p>0. php</p>
  <p>1. node</p>
  <p>2. ruby</p>
</div>

同樣的構造也適用於對象:

- var languages = {'php': -1, 'node': 2, 'ruby':1}
div
  each value, key in languages
    p= key + ": " + value

上面的 Jade 編譯成 HTML 輸出:

<div>
  <p>php: -1</p>
  <p>node: 2</p>
  <p>ruby: 1</p>
</div>

過濾器

當存在以不同語言編寫的文本塊時,使用過濾器。例如,Markdown 的過濾器如下所示:

p
 :markdown
   # Practical Node.js

這本書(http://expressjsguide.com),確實有助於掌握現代Web開發所需的許多組件。

■ 注意 Markdown 模塊仍然需要安裝。 marked 和 markdown NPM 包通常用於此目的。不需要額外的配置,直接安裝在項目本地的node_modules 文件夾。

插值

Jade 中的插值是通過 #{name} 實現的 .例如輸出 title 在一個段落中,執行以下操作:

- var title = "Express.js Guide"
p Read the #{title} in PDF, MOBI and EPUB

插值在模板編譯時處理;因此,不要在可執行的 JavaScript (- )。

案例

這是 case 的示例 玉中說法:

- var coins = Math.round(Math.random()*10)
case coins
  when 0
    p You have no money
  when 1
    p You have a coin
default
  p You have #{coins} coins!

混合

Mixin 是接受參數並生成一些 HTML 的函數。聲明語法為 mixin name(param,param2,...) , 用法是 +name(data) .例如:

mixin row(items)
  tr
    each item, index in items
      td= item 

mixin table(tableData)
  table
    each row, index in tableData
      +row(row)
- var node = [{name: "express"}, {name: "hapi"}, {name: "derby"}]
+table(node)
- var js = [{name: "backbone"}, {name: "angular"}, {name: "ember"}]
+table(js)

上面的模板和數據生成了這個 HTML:

<table>
  <tr>
    <td>express</td>
  </tr>
  <tr>
    <td>hapi</td>
  </tr>
  <tr>
    <td>derby</td>
  </tr>
</table>
<table>
  <tr>
    <td>backbone</td>
  </tr>
  <tr>
    <td>angular</td>
  </tr>
  <tr>
    <td>ember</td>
  </tr>
</table>

包括

include 是一種將邏輯拆分為單獨文件的方法,以便在多個文件中重用它。這是一種自上而下的方法;我們規定在包含另一個文件的文件中使用什麼。首先處理包含的文件(我們可以在那裡定義本地),然後處理包含的文件(我們可以使用之前定義的本地)。

要包含 Jade 模板,請使用 include /path/filename。例如,在文件 A 中:

include ./includes/header

請注意,模板名稱及其路徑不需要雙引號或單引號。可以向上遍歷樹:

include ../includes/footer

但是,沒有辦法為文件和路徑使用動態值(使用變量),因為包含/部分是在編譯時處理的(而不是在運行時)。

擴展

extend 是一種自下而上的方法(與 include 相反 ),從某種意義上說,包含的文件命令它想要替換主文件的哪些部分。它的工作方式是擴展 filenameblock blockname 聲明:

file_a

block header
  p some default text
block content
  p Loading ...
block footer
  p copyright

file_b

extend file_a
block header
  p very specific text
block content
  .main-content

單獨使用翡翠

模板引擎並不總是與 Node.js(以及 Express.js 等框架)一起使用。有時,我們可能只想以獨立的方式使用 Jade。用例包括生成電子郵件模板、部署前預編譯 Jade 和調試。在本節中,我們執行以下操作:

  • 安裝 Jade 模塊
  • 創建我們的第一個 Jade 文件
  • 創建一個使用 Jade 文件的 Node.js 程序
  • 比較jade.compile , jade.render , 和 jade.renderFile

添加 jade 依賴於你的項目,或者如果你從一個空的項目文件夾從頭開始,請執行以下操作:

  • 創建一個空的node_modules $ mkdir node_modules 的文件夾
  • 安裝並添加jadepackage.json 使用 $ npm install jade –save .請參見圖 4–1 中的結果。

圖 4-1。安裝翡翠

假設我們有一些發送電子郵件的 Node.js 腳本,我們需要使用模板為電子郵件動態生成 HTML。這就是它的外觀(文件 jade-example.jade ):

.header
  h1= title
  p
.body
  p= body
.footer
  div= By
    a(href="http://twitter.com/#{author.twitter}")= author.name
ul
  each tag, index in tags
    li= tag

在這種情況下,我們的 Node.js 腳本需要使用以下數據來填充或填充此模板:

  • 標題:字符串
  • 正文:字符串
  • 作者:字符串
  • 標籤:數組

我們可以從多個來源(數據庫、文件系統、用戶輸入等)中提取這些變量。例如,在 jade-example.js 文件,我們對 title 使用硬編碼值 , author , tags , 但通過 body 的命令行參數 :

var jade = require('jade'),
  fs = require('fs'); 
var data = {
  title: "Practical Node.js",
  author: {
    twitter: "@azat_co",
    name: "Azat"
  },
  tags: ['express', 'node', 'javascript']
}
data.body = process.argv[2];

fs.readFile('jade-example.jade', 'utf-8', function(error, source){
  var template = jade.compile(source);
  var html = template(data)
  console.log(html)
});

這樣,當我們運行 $ node jade-example.js 'email body' ,我們得到如圖4-2所示的輸出。

圖 4-2。玉示例輸出結果

“美化”的 HTML 輸出如下:

<div class="header">
    <h1>Practical Node.js</h1>
    <p></p>
</div>
<div class="body">
    <p>email body</p>
</div> 
<div class="footer">
    <div><a href="http://twitter.com/@azat_co"> Azat</a>
    </div>
    <ul>
        <li>express</li>
        <li>node</li>
        <li>javascript</li>
    </ul>
</div>

除了 jade.compile() , Jade API 有函數 jade.render()jade.renderFile() .例如,可以用 jade.render() 重寫之前的文件 :

var jade = require('jade'),
  fs = require('fs');

var data = {
  title: "Practical Node.js",
  author: {
    twitter: "@azat_co",
    name: "Azat"
  },
  tags: ['express', 'node', 'javascript']
}
data.body = process.argv[2];

//jade.render
fs.readFile('jade-example.jade', 'utf-8', function(error, source){
  var html = jade.render(source, data)
  console.log(html)
});

此外,使用 jade.renderFile , jade-example.js file 更緊湊:

var jade = require('jade'),
  fs = require('fs');

var data = {
  title: "Practical Node.js",
  author: {
    twitter: "@azat_co",
    name: "Azat"
  },
  tags: ['express', 'node', 'javascript']
}
data.body = process.argv[2];

//jade.renderFile

jade.renderFile('jade-example.jade', data, function(error, html){
  console.log(html)
});

注意 使用 -g 安裝 Jade 後也可以作為命令行工具使用 或 --global 通過 NPM 選擇。有關詳細信息,請運行 jade -h 或者查看官方文檔(http://jade-lang.com/command-line/)。

要在瀏覽器中使用 Jade,可以使用 browserify (https://github.com/substack/node-browserify) 及其 jamify (https://github.com/substack/node-jadeify) 中間件。

注意 要在前端(瀏覽器)和服務器端使用相同的 Jade 模板,我推薦 jade-browser  (https://www.npmjs.org/package/jade-browser) 由 Storify 開發,我在那里工作期間曾擔任過一段時間的維護者。 jade-browser 充當 Express.js 中間件,它向瀏覽器公開服務器端模板以及有用的實用程序功能。 GitHub:ttps://github.com/storify/jade-browser。

這篇關於 Jade 的快速指南到此結束。在下一篇文章中,我將介紹相關主題:

  • 車把語法
  • 車把獨立使用
  • Express.js 4 中 Jade 和 Handlebars 的使用
  • 項目:將 Jade 模板添加到博客

Tutorial JavaScript 教程
  1. 選擇牆紙時不能做什麼

  2. 使用 Github 構建免費的 NextJS 評論系統 [第 2/2 部分]

  3. 追加 VS appendChild

  4. 如何使用javascript從一個頁面轉到另一個頁面?

  5. 什麼是轉發 ref 以及如何使用它?

  6. 零代碼行在 Kubernetes 中部署微服務

  7. 角斗士

  1. 請停止使用代理查詢

  2. JavaScript 中 For 循環的 3 種風格以及何時使用它們

  3. 使用 Firebase🔥 集成、AntDesign 和 Reach Router 創建我的第一個 React 應用程序

  4. 如何將事件綁定到 JavaScript 中動態創建的元素

  5. 如何在 Vue 3 中通過 Composition API 使用 Watch

  6. 數組 forEach JavaScript |功能

  7. 使用 Python 進行 Web 抓取演練

  1. JavaScript — 原始值與參考值(修復對象可變性的方法)

  2. 使用 OpenAPI 和 JSDoc 記錄 Express REST API

  3. ES6 承諾 |承諾.all |承諾.race | Promise.all 已解決

  4. 你好亞像素世界