實在是受不了 adobe dreamweaver 的肥大,每次只要想將 html 製作共用的模時,就覺得開啟很慢,而在同步時也很慢。
在正好在研究 mac 軟體 Prepros 時發現有Pug(jade)、Haml、Slim 支援樣板引擎的格式,在找了一些相關的文章後發現 Pug(jade) 比較如我所想要的,正好梅干也有相關的文章(真的是太有緣了,我想真的有機會就拜為師)。
1-Jade基本寫法
1 2 3 4 5 6 7 8 9 10 11 12 | doctype html html head title helloJade style. .style-1{ font-size: 25px; color: red; } body h1.style-1 Jade Basic p 這是Jade基本寫法 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <html> <head> <title>CodePen - Jade基本規則</title> <style> .style-1 { font-size: 25px; color: red; } </style> </head> <body> <title>helloJade</title> <h1 class="style-1">Jade Basic</h1> <p>這是Jade基本寫法</p> </body> </html> |
See the Pen Jade基本規則 by Jimmy_Wu (@Jimmy_Wu) on CodePen.
1-1-屬性(Attributes)
標籤特性看起來與 html(有額外逗號)相似,但它們的值都只是普通的 JavaScript。
1 2 3 | a(href='google.com') Google a(class='button' href='google.com') Google a(class='button', href='google.com') Google |
1 | <a href="google.com">Google</a><a href="google.com" class="button">Google</a><a href="google.com" class="button">Google</a> |
有很多屬性,可以把它們分成多行
1 2 3 4 5 | input( type='checkbox' name='agreement' checked ) |
1 | <input type="checkbox" name="agreement" checked="checked" /> |
不轉義特性(Unescaped Attributes)
1 2 | div( escaped="< code >" ) div( unescaped!="< code >" ) |
1 2 | <div escaped="< code >" ></div> <div unescaped="< code >"></div> |
Class 實字(Class Literal)
類別可以使用 .className 語法來定義
1 2 | a.button .content |
1 2 | <a class="button"></a> <div class="content"></div> |
Style 特性(Style Attributes)
1 | a(style={color: 'red', background: 'green'}) |
1 | <a style="color:red;background:green"></a> |
Class 特性(Class Attributes)
class 特性可以是字串(就像任何普通的特性),但它也可以是 class 名稱的陣列,在從 JavaScript 產生時很方便
1 2 3 4 | - var classes = ['foo', 'bar', 'baz'] a(class=classes) //- the class attribute may also be repeated to merge arrays a.bang(class=classes class=['bing']) |
1 2 | <a class="foo bar baz"></a> <a class="bang foo bar baz bing"></a> |
ID 實字(ID Literal)
ID 可以使用 #IDName 語法來定義
1 2 | a#main-link #content |
1 2 | <a id="main-link"></a> <div id="content"></div> |
&attributes
讀作 “and attributes”, &attributes 語法可用來分解物件成元素的特性。
1 | div#foo(data-bar="foo")&attributes({'data-foo': 'bar'}) |
1 | <div id="foo" data-bar="foo" data-foo="bar"></div> |
1-2-程式碼 (code)
jade 三種類型的 code
第一種:無緩衝程式碼(Unbuffered Code)
這種類型的 code 以一個中橫線 - 開頭,不會直接輸出
1 2 3 | ul -for (var x = 0; x < 3; x++) li item |
1 2 3 4 5 | <ul> <li>item</li> <li>item</li> <li>item</li> </ul> |
第二種:緩衝程式碼 (Buffered Code)
此類型的 code 以一個等號 = 開頭;為了安全, jade 會將 html 代碼進行轉義
1 2 | p = 'This code is <escaped>!' |
1 2 | <p>This code is <escaped>! </p> |
也可以把 = 及後面的文本與 tag 放在同一行
1 | p= 'This code is' + ' <escaped>!' |
1 | <p>This code is <escaped>!</p> |
第三種:無轉義緩衝的程式碼(Unescaped Buffered Code)
此類型的 code 以一個嘆號加一個等號 != 開頭,而且 jade 不會轉義 html 代碼;
如果是變量,可以寫成 !{var} 作用於 #{val},只是不轉義;
1 2 | p != 'This code is <strong>not</strong> escaped!' |
1 2 | <p>This code is <strong>not</strong> escaped! </p> |
1 | p!= 'This code is <strong>not</strong> escaped!' |
1 | <p>This code is <strong>not</strong> escaped!</p> |
1-3-註解/註釋 (comments)
單行註解
jade 使用雙斜線 // 進行單行註釋;
如果不想讓註釋的內容顯示到生成的 html 代碼中,可以在雙斜線後跟一個單橫線 //-
1 2 3 4 5 6 7 | //just some paragraphs p foo p bar //-will not output within markup p foo p bar |
1 2 3 4 5 6 | <!--just some paragraphs--> <p>foo</p> <p>bar</p> <p>foo</p> <p>bar</p> |
區塊註解 (Block Comments)
雙斜線 // 後面的註釋內容換行並縮進可進行塊級註釋;
1 2 3 4 | body // As much text as you want can go here. |
1 2 3 4 5 6 | <body> <!-- As much text as you want can go here. --> </body> |
條件式註解 (Conditional Comments)
Jade 沒有任何針對條件式註解的特殊語法。 如果你的一行以 < 開頭,那它會被視為純文本。 所以就使用普通的 HTML 風格條件式註解
條件註釋,只有在 IE10,及以下的 IE瀏覽器才支持,jade中的條件註釋沒有特別的語法,而是直接採用一般的 html 條件註釋
1 2 3 4 5 6 | <!--[if IE 8]> <html lang="en" class="lt-ie9"> <![endif]--> <!--[if gt IE 8]><!--> <html lang="en"> <!--<![endif]--> |
1 2 3 4 5 6 | <!--[if IE 8]> <html lang="en" class="lt-ie9"> <![endif]--> <!--[if gt IE 8]><!--> <html lang="en"> <!--<![endif]--> |
1-4-doctype
html5
jade:doctype html
html: <!DOCTYPE html>
xml
jade:doctype xml
html: <?xml version="1.0" encoding="utf-8" ?>
strict
jade:doctype strict
html: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
1-5-純文本(Plain Text)
方式一:管線文本 (Piped Text)
Piped Text 在文本的開頭使用管道符 |
1 2 3 | | Plain text can include <strong>html</strong> p | It must always be on its own line |
1 2 | Plain text can include <strong>html</strong> <p>It must always be on its own line</p> |
方式二:在 Tag 中的內嵌 (Inline in a Tag)
文本與 tag 放到同一行
1 2 | .content content #content.content.box content |
1 2 | <div class="content">content</div> <div id="content" class="content box">content</div> |
方式三:適合有大量文本 (Block in a Tag)
在 tag 後使用一個點號 ., tag 與 .之間不能有空格
1 2 3 4 5 | p. Jade is a terse and simplae templating language with a strong focus on performance and powerful features. |
1 2 3 4 5 6 | <p> Jade is a terse and simplae templating language with a strong focus on performance and powerful features. </p> |
1-6-迭代(Iteration)
主要的迭代方法, each 和 while
each
1 2 3 | ul.red-text each val in ["這是第一點", "這是第二點", "這是第三點", 4, 5] li= val |
See the Pen jade 迭代(Iteration)-each by Jimmy_Wu (@Jimmy_Wu) on CodePen.
另外 each .. in 的用法
1 2 3 | ul each val, index in {'one': 'one','two': 'world','three': 'one', 'four': 'dream'} li= index + ': ' + val |
1 2 3 4 5 6 | <ul> <li>one: one</li> <li>two: world</li> <li>three: one</li> <li>four: dream</li> </ul> |
while
1 2 3 4 | - var n = 0 ul while n < 4 li= n++ |
1 2 3 4 5 6 | <ul> <li>0</li> <li>1</li> <li>2</li> <li>3</li> </ul> |
1-1-5-過濾器 (filters)
過濾器,語法是一個前置的冒號 : 加上過濾器的名稱;
jade 支持的過濾器有如下幾種:
- :stylus 必須已安裝 stylus
- :less 必須已安裝 less.js
- :markdown 必須已安裝 markdown-js 或 node-discount
- :cdate
- :coffeescript 必須已安裝 coffee-script
2-Jade 模版實際運用
2-2-Jade Extend (繼承)
像 Dreamweaver 網頁模版的概念,透過已製作好的模版後 (檔案 tpl.jade),再針對模版 (檔案 tpl.jade) 修改裡面的元素與內容,替換原模版 (檔案 tpl.jade)的區塊 (檔案 extends.jade),。
在製作模版時,當可替換的元素,則用 block 標示, block 後接替換區塊的命名,例如: block webtitle,但注意替換區塊的命名後更換的元素區塊要在退位。
tpl.jade
1 2 3 4 5 6 7 8 9 10 11 12 13 | doctype html html(lang="zh-TW") head meta(charset='utf-8') meta(http-equiv='X-UA-Compatible', content='IE=edge') meta(name='viewport', content='width=device-width, initial-scale=1') block webtitle title 無標題 body block h1title h1 這是原本的H1 block postcontent div 這是原本內容 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <!DOCTYPE html> <html lang="zh-TW"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>無標題</title> </head> <body> <h1>這是原本的H1</h1> <main>這是main</main> <div>這是原本內容</div> </body> </html> |
extends.jade
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //- 指定原模版路徑 extends ./tpl.jade //- 指定更換原模版的區塊 block webtitle //block webtitle title 阿原title block h1title //block h1title h1 阿原h1 block postcontent //block postcontent main.main 這是main換後在加入Class div.container 引入指定目地路徑,所更換換區塊內容 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <!DOCTYPE html> <html lang="zh-TW"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!--block webtitle--> <title>阿原title</title> </head> <body> <!--block h1title--> <h1>阿原h1</h1> <h1>這是原本的H1</h1> <!--block postcontent--> <main class="main">這是main換後在加入Class</main> <div class="container">引入指定目地路徑,所更換換區塊內容 </div> <main>這是main</main> <div>這是原本內容</div> </body> </html> |
修改的繼承(Extends)檔案,註解要使用 //- 註解內容 才能正確註解起來,若使用 //註解內容 (JS的註解) 的話,輸出 html 檔案會產生 <!-- 註解內容 -->
2-2-Jade Includes (匯入)
匯入這功能,就像一般的php或是apsx一樣,可以將內容直接匯入進來,就像拷貝貼上一樣,而這以前大部分都用iframe來製作,但現有了匯入後,就能將版型拆成多隻後,再把它合併起來,因此當要修改時就更方便了。
1 2 3 4 5 6 7 | // head.jade head meta(chartset='utf-8') meta(name='description',content='有本事就來呀') link(href='style.css',rel='stylesheet') title jade includes // /head.jade |
1 2 3 4 | // footer.jade #footer p copyright (c) 2014-10-31 // /footer.jade |
1 2 3 4 5 6 7 | doctype html html include ./head.jade body header 有本事 #content 內容 include ./footer.jade |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <!DOCTYPE html> <html> <!-- head.jade--> <head> <meta chartset="utf-8"> <meta name="description" content="有本事就來呀"> <link href="style.css" rel="stylesheet"> <title>jade includes </title> </head> <!-- /head.jade--> <body> <header>有本事</header> <div id="content">內容</div> <!-- footer.jade--> <div id="footer"> <p>copyright (c) 2014-10-31</p> </div> <!-- /footer.jade--> </body> </html> |
2-3-Jade 混入(mixins)
使用 mixin 可以創建可重用的代碼塊
minxin = mixinName,調用的時候直接 +mixinName
1 2 3 4 5 6 7 8 9 | //- Declaration mixin list ul li foo li bar li baz //- Use +list +list |
1 2 3 4 5 6 7 8 9 10 | <ul> <li>foo</li> <li>bar</li> <li>baz</li> </ul> <ul> <li>foo</li> <li>bar</li> <li>baz</li> </ul> |
上層元素下接續結構
1 2 3 4 5 6 7 8 | // mixins.jade ol mixin link(url,linkname,linkclass) li a(href=url,class=linkclass)=linkname +link('https://apple.com.tw','apple','btn') +link('http://google.com','google','btn') +link('http://yahoo.com.tw','yahoo','btn') |
1 2 3 4 5 6 | <!-- mixins.jade--> <ol> <li><a class="btn" href="https://apple.com.tw">apple</a></li> <li><a class="btn" href="http://google.com">google</a></li> <li><a class="btn" href="http://yahoo.com.tw">yahoo</a></li> </ol> |
使用的時候,還可以給 mixin 定義參數,當作一個函數來使用
1 2 3 4 5 6 | mixin pet(name) li.pet= name ul +pet('cat') +pet('dog') +pet('pig') |
1 2 3 4 5 | <ul> <li class="pet">cat</li> <li class="pet">dog</li> <li class="pet">pig</li> </ul> |
Mixin Blocks
mixin 也可以使用像 include 那樣的塊
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | mixin article(title) .article .article-wrapper h1= title if block block else p No content provided +article('Hello world') +article('Hello world') p This is my p Amazing article |
1 2 3 4 5 6 7 8 9 10 11 12 13 | <div class="article"> <div class="article-wrapper"> <h1>Hello world</h1> <p>No content provided</p> </div> </div> <div class="article"> <div class="article-wrapper"> <h1>Hello world</h1> <p>This is my</p> <p>Amazing article</p> </div> </div> |
Mixin Attributes
1 2 3 4 5 | mixin link(href, name) //- attributes == {class: "btn"} a(class!=attributes.class, href=href)= name +link('/foo', 'foo')(class="btn") |
3-模版功能與區塊元件化使用注意事項
- Jade 的 Extends (繼承) 製做出來的模版,無法直接使用 Includes (匯入) 在模版內混用。
- 套用 Extends (繼承) 模版路徑的 jade 檔, block 區塊名稱 沒有在下方加入內容的話,是直接取用模版內的內容與架,但如果有使用要取代模版內區塊內的內容與架構,可以在 block 區塊名稱 下方接著帶入內容與架構就可以取代。
- 注意 Extends (繼承) 進來的空白鍵或是 Tab 鍵字元階層,如果沒包在下層的話,會無法帶入或是取代模版內容與架構。
tpl.jade
1 2 3 4 5 6 7 8 9 10 11 12 13 | doctype html html(lang="zh-TW") head meta(charset='utf-8') meta(http-equiv='X-UA-Compatible', content='IE=edge') meta(name='viewport', content='width=device-width, initial-scale=1') block webtitle title 無標題 body block h1title h1 這是原本的H1 block postcontent div 這是原本內容 |
include footer.jade 的內容
1 2 3 4 | // footer.jade #footer p copyright (c) 2014-10-31 // /footer.jade |
extends.jade
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //- 指定原模版路徑 extends ./tpl.jade //- 指定更換原模版的區塊 block webtitle //block webtitle title 阿原title block h1title //block h1title h1 阿原h1 block postcontent include ./footer.jade // 加入的 include footer.jade 區塊 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <!DOCTYPE html> <html lang="zh-TW"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!--block webtitle--> <title>阿原title</title> </head> <body> <!--block h1title--> <h1>阿原h1</h1> <h1>這是原本的H1</h1> <!--block postcontent--> <!-- footer.jade--> <div id="footer"> <p>copyright (c) 2014-10-31</p> </div> <!-- /footer.jade--> <!--/block postcontent--> </body> </html> |
4-Jade除錯與注意事項
在退為鍵使用上要注意,如果主要使用 Tab 鍵來退位的話,在檔案中就都要使用 TAB 退位來控制,若如果使用空白鍵退位的話,就全用空白鍵,如果混用的話輸出到 html 檔時會發生錯誤無法輸出成功。
線上直接轉換
- HTML2Jade – 線上直接將 HTML 轉 Jade ,中文也不會有問題
- vidalab/meteor-html2jade
– 線上直接將 HTML 轉 Jade ,中文也不會有問題- HTML to Jade converter – 梅干所提到的轉換網站,但中文的 HTML 會轉成亂碼。
1 | <a href="/foo" class="btn">foo</a> |
資料來源
Jade-正體中文文件-語言參考
梅問題教學網-JADE基本使用教學:規則、文字、繼承、匯入、函式寫法
Baking Bootstrap Snippets with Jade
Jade樣板引擎入門(1)-基本概念與用法
JAYIER’S WEB-NOTES – Jade中文教程