Jade教程


Jade 是一個高性能的模板引擎,它深受 Haml 影響,它是用 JavaScript 實現的,並且可以供 Node 使用。

 

  • 如何在jade模板上加業務邏輯

 

 

 if res.length==5
    h1= title+"你大爺的"
  else
    h1=res.join(',')

 

 

 

  • 如何寫前端js代碼

script(type='text/javascript').
  $(document).ready(function () {
    alert('馬良設計');
  })

請注意后面有個.

引用前端的js文件

script(src='/javascripts/jquery-1.10.2.js')
  • 如何寫前端css代碼

引用css樣式

 link(rel='stylesheet', href='/stylesheets/style.css')
    style.
      html,body{
        background-color: #00B7FF;
        margin:0;
        padding:0;
        border:0;
      }

引入css樣式文件和樣式

  • 如何加頁面標簽

html 

它會被轉換為 <html></html>

標簽也是可以有 id 的:

div#container 

它會被轉換為 <div id="container"></div>

怎么加 class 呢?

div.user-details

轉換為 <div class="user-details"></div>

多個 class 和 id? 也是可以搞定的:

div#foo.bar.baz 

轉換為 <div id="foo" class="bar baz"></div>

不停的 div div div 很討厭啊 , 可以這樣:

#foo .bar 

這個算是我們的語法糖,它已經被很好的支持了,上面的會輸出:

<div id="foo"></div><div class="bar"></div> 

標簽文本

只需要簡單的把內容放在標簽之后:

p wahoo! 

它會被渲染為 <p>wahoo!</p>.

很帥吧,但是大段的文本怎么辦呢:

p
  | foo bar baz
  | rawr rawr
  | super cool | go jade go 

渲染為 <p>foo bar baz rawr.....</p>

怎么和數據結合起來? 所有類型的文本展示都可以和數據結合起來,如果我們把 { name: 'tj', email: 'tj@vision-media.ca' } 傳給編譯函數,下面是模板上的寫法:

#user #{name} &lt;#{email}&gt; 

它會被渲染為 <div id="user">tj &lt;tj@vision-media.ca&gt;</div>

當就是要輸出 #{} 的時候怎么辦? 轉義一下!

p \#{something} 

它會輸出 <p>#{something}</p>

同樣可以使用非轉義的變量 !{html}, 下面的模板將直接輸出一個 <script> 標簽:

- var html = "<script></script>" | !{html} 

內聯標簽同樣可以使用文本塊來包含文本:

label | Username: input(name='user[name]') 

或者直接使用標簽文本:

label Username: input(name='user[name]') 

 包含文本的標簽,比如 <script><style>, 和 <textarea> 不需要前綴 | 字符, 比如:

html
  head
    title Example
    script
      if (foo) { bar(); } else { baz(); } 

這里還有一種選擇,可以使用 . 來開始一段文本塊,比如:

p.
  foo asdf
  asdf
   asdfasdfaf
   asdf
  asd.

會被渲染為:

<p>foo asdf asdf asdfasdfaf asdf asd . </p> 

這和帶一個空格的 . 是不一樣的, 帶空格的會被 Jade 的解析器忽略,當作一個普通的文字:

p . 

渲染為:

<p>.</p> 

需要注意的是文本塊需要兩次轉義。比如想要輸出下面的文本:

</p>foo\bar</p> 

使用:

p.
  foo\\bar

注釋

單行注釋和 JavaScript 里是一樣的,通過 // 來開始,並且必須單獨一行:

// just some paragraphs p foo p bar 

渲染為:

<!-- just some paragraphs --> <p>foo</p> <p>bar</p> 

Jade 同樣支持不輸出的注釋,加一個短橫線就行了:

//- will not output within markup p foo p bar 

渲染為:

<p>foo</p> <p>bar</p> 

塊注釋

塊注釋也是支持的:

body
  // #content h1 Example 

渲染為:

<body> <!-- <div id="content"> <h1>Example</h1> </div> --> </body> 

Jade 同樣很好的支持了條件注釋:

body
  //if IE a(href='http://www.mozilla.com/en-US/firefox/') Get Firefox 

渲染為:

<body> <!--[if IE]> <a href="http://www.mozilla.com/en-US/firefox/">Get Firefox</a> <![endif]--> </body> 

內聯

Jade 支持以自然的方式定義標簽嵌套:

ul li.first a(href='#') foo li a(href='#') bar li.last a(href='#') baz 

塊展開

塊展開可以幫助你在一行內創建嵌套的標簽,下面的例子和上面的是一樣的:

ul li.first: a(href='#') foo li: a(href='#') bar li.last: a(href='#') baz 

Case

case 表達式按下面這樣的形式寫:

html
  body
    friends = 10 case friends when 0 p you have no friends when 1 p you have a friend default p you have #{friends} friends 

塊展開在這里也可以使用:

friends = 5 html body case friends when 0: p you have no friends when 1: p you have a friend default: p you have #{friends} friends 

屬性

Jade 現在支持使用 ( 和 ) 作為屬性分隔符

a(href='/login', title='View login page') Login 

當一個值是 undefined 或者 null 屬性  會被加上,
所以呢,它不會編譯出 'something="null"'.

div(something=null) 

Boolean 屬性也是支持的:

input(type="checkbox", checked) 

使用代碼的 Boolean 屬性只有當屬性為 true 時才會輸出:

input(type="checkbox", checked=someValue) 

多行同樣也是可用的:

input(type='checkbox', name='agreement', checked) 

多行的時候可以不加逗號:

input(type='checkbox' name='agreement' checked) 

加點空格,格式好看一點?同樣支持

input(
  type='checkbox' name='agreement' checked) 

冒號也是支持的:

rss(xmlns:atom="atom") 

假如我有一個 user 對象 { id: 12, name: 'tobi' }
我們希望創建一個指向 /user/12 的鏈接 href, 我們可以使用普通的 JavaScript 字符串連接,如下:

a(href='/user/' + user.id)= user.name 

或者我們使用 Jade 的修改方式, 這個我想很多使用 Ruby 或者 CoffeeScript 的人會看起來像普通的 JS..:

a(href='/user/#{user.id}')= user.name 

class 屬性是一個特殊的屬性,你可以直接傳遞一個數組,比如 bodyClasses = ['user', 'authenticated'] :

body(class=bodyClasses) 

HTML

內聯的 HTML 是可以的,我們可以使用管道定義一段文本 :

html
  body
    | <h1>Title</h1> | <p>foo bar baz</p> 

或者我們可以使用 . 來告訴 Jade 我們需要一段文本:

html
  body.
    <h1>Title</h1> <p>foo bar baz</p> 

上面的兩個例子都會渲染成相同的結果:

<html><body><h1>Title</h1> <p>foo bar baz</p> </body></html> 

這條規則適應於在 Jade 里的任何文本:

html body h1 User <em>#{name}</em> 

Doctypes

添加文檔類型只需要簡單的使用 !!!, 或者 doctype 跟上下面的可選項:

!!! 

會渲染出 transitional 文檔類型, 或者:

!!! 5 

!!! html 

doctype html 

Doctype 是大小寫不敏感的, 所以下面兩個是一樣的:

doctype Basic doctype basic 

當然也是可以直接傳遞一段文檔類型的文本:

doctype html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" 

渲染后:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"> 

會輸出 HTML5 文檔類型. 下面的默認的文檔類型,可以很簡單的擴展:

var doctypes = exports.doctypes = {
  '5': '<!DOCTYPE html>', 'xml': '<?xml version="1.0" encoding="utf-8" ?>', 'default': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">', 'transitional': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">', 'strict': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">', 'frameset': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">', '1.1': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">', 'basic': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">', 'mobile': '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">' }; 

通過下面的代碼可以很簡單的改變默認的文檔類型:

    jade.doctypes.default = 'whatever you want'; 

過濾器

過濾器前綴 :, 比如 :markdown 會把下面塊里的文本交給專門的函數進行處理。查看頂部 特性 里有哪些可用的過濾器。

body :markdown Woah! jade _and_ markdown, very **cool** we can even link to [stuff](http://google.com) 

渲染為:

<body><p>Woah! jade <em>and</em> markdown, very <strong>cool</strong> we can even link to <a href="http://google.com">stuff</a></p></body> 

代碼

Jade 目前支持三種類型的可執行代碼。第一種是前綴 -, 這是不會被輸出的:

- var foo = 'bar'; 

這可以用在條件語句或者循環中:

- for (var key in obj) p= obj[key] 

由於 Jade 的緩存技術,下面的代碼也是可以的:

- if (foo) ul li yay li foo li worked - else p oh no! didnt work 

哈哈,甚至是很長的循環也是可以的:

- if (items.length) ul - items.forEach(function(item){ li= item - }) 

所以你想要的!

下一步我們要 轉義 輸出的代碼,比如我們返回一個值,只要前綴一個 =

- var foo = 'bar' = foo h1= foo 

它會渲染為 bar<h1>bar</h1>. 為了安全起見,使用 = 輸出的代碼默認是轉義的,如果想直接輸出不轉義的值可以使用 !=

p!= aVarContainingMoreHTML 

Jade 同樣是設計師友好的,它可以使 JavaScript 更直接更富表現力。比如下面的賦值語句是相等的,同時表達式還是通常的 JavaScript:

- var foo = 'foo ' + 'bar' foo = 'foo ' + 'bar' 

Jade 會把 ifelse ifelseuntilwhileunless 同別的優先對待, 但是你得記住它們還是普通的 JavaScript:

if foo == 'bar' ul li yay li foo li worked else p oh no! didnt work 

循環

盡管已經支持 JavaScript 原生代碼,Jade 還是支持了一些特殊的標簽,它們可以讓模板更加易於理解,其中之一就是 each, 這種形式:

each VAL[, KEY] in OBJ 

一個遍歷數組的例子 :

- var items = ["one", "two", "three"] each item in items li= item 

渲染為:

<li>one</li> <li>two</li> <li>three</li> 

遍歷一個數組同時帶上索引:

items = ["one", "two", "three"] each item, i in items li #{item}: #{i} 

渲染為:

<li>one: 0</li> <li>two: 1</li> <li>three: 2</li> 

遍歷一個數組的鍵值:

obj = { foo: 'bar' } each val, key in obj li #{key}: #{val} 

將會渲染為:<li>foo: bar</li>

Jade 在內部會把這些語句轉換成原生的 JavaScript 語句,就像使用 users.forEach(function(user){, 詞法作用域和嵌套會像在普通的 JavaScript 中一樣:

each user in users each role in user.roles li= role 

如果你喜歡,也可以使用 for :

for user in users for role in user.roles li= role 

條件語句

Jade 條件語句和使用了(-) 前綴的 JavaScript 語句是一致的,然后它允許你不使用圓括號,這樣會看上去對設計師更友好一點,
同時要在心里記住這個表達式渲染出的是 常規 JavaScript:

for user in users if user.role == 'admin' p #{user.name} is an admin else p= user.name 

和下面的使用了常規 JavaScript 的代碼是相等的:

for user in users - if (user.role == 'admin') p #{user.name} is an admin - else p= user.name 

Jade 同時支持 unless, 這和 if (!(expr)) 是等價的:

for user in users unless user.isAnonymous p | Click to view a(href='/users/' + user.id)= user.name 

模板繼承

Jade 支持通過 block 和 extends 關鍵字來實現模板繼承。 一個塊就是一個 Jade 的 block ,它將在子模板中實現,同時是支持遞歸的。

Jade 塊如果沒有內容,Jade 會添加默認內容,下面的代碼默認會輸出 block scriptsblock content, 和 block foot.

html head h1 My Site - #{title} block scripts script(src='/jquery.js') body block content block foot #footer p some footer content 

現在我們來繼承這個布局,簡單創建一個新文件,像下面那樣直接使用 extends,給定路徑(可以選擇帶 .jade 擴展名或者不帶). 你可以定義一個或者更多的塊來覆蓋父級塊內容, 注意到這里的 foot 塊 沒有 定義,所以它還會輸出父級的 "some footer content"。

extends extend-layout block scripts script(src='/jquery.js') script(src='/pets.js') block content h1= title each pet in pets include pet 

同樣可以在一個子塊里添加塊,就像下面實現的塊 content 里又定義了兩個可以被實現的塊 sidebar 和 primary,或者子模板直接實現 content

extends regular-layout block content .sidebar block sidebar p nothing .primary block primary p nothing 

前置、追加代碼塊

Jade允許你 替換 (默認)、 前置 和 追加 blocks. 比如,假設你希望在 所有 頁面的頭部都加上默認的腳本,你可以這么做:

html head block head script(src='/vendor/jquery.js') script(src='/vendor/caustic.js') body block content 

現在假設你有一個Javascript游戲的頁面,你希望在默認的腳本之外添加一些游戲相關的腳本,你可以直接append上代碼塊:

extends layout block append head script(src='/vendor/three.js') script(src='/game.js') 

使用 block append 或 block prepend 時 block 是可選的:

extends layout append head script(src='/vendor/three.js') script(src='/game.js') 

包含

Includes 允許你靜態包含一段 Jade, 或者別的存放在單個文件中的東西比如 CSS, HTML 非常常見的例子是包含頭部和頁腳。 假設我們有一個下面目錄結構的文件夾:

./layout.jade
./includes/ ./head.jade ./tail.jade 

下面是 layout.jade 的內容:

html
  include includes/head body h1 My Site p Welcome to my super amazing site. include includes/foot 

這兩個包含 includes/head 和 includes/foot 都會讀取相對於給 layout.jade 參數filename 的路徑的文件, 這是一個絕對路徑,不用擔心Express幫你搞定這些了。Include 會解析這些文件,並且插入到已經生成的語法樹中,然后渲染為你期待的內容:

<html> <head> <title>My Site</title> <script src="/javascripts/jquery.js"> </script><script src="/javascripts/app.js"></script> </head> <body> <h1>My Site</h1> <p>Welcome to my super lame site.</p> <div id="footer"> <p>Copyright>(c) foobar</p> </div> </body> </html> 

前面已經提到,include 可以包含比如 HTML 或者 CSS 這樣的內容。給定一個擴展名后,Jade 不會把這個文件當作一個 Jade 源代碼,並且會把它當作一個普通文本包含進來:

html
  head
    //- css and js have simple filters that wrap them in <style> and <script> tags, respectively include stylesheet.css include script.js body //- "markdown" files will use the "markdown" filter to convert Markdown to HTML include introduction.markdown //- html files have no filter and are included verbatim include content.html 

Include 也可以接受塊內容,給定的塊將會附加到包含文件 最后 的塊里。 舉個例子,head.jade 包含下面的內容:

head script(src='/jquery.js') 

我們可以像下面給include head添加內容, 這里是添加兩個腳本.

html include head script(src='/foo.js') script(src='/bar.js') body h1 test 

在被包含的模板中,你也可以使用yield語句。yield語句允許你明確地標明include的代碼塊的放置位置。比如,假設你希望把代碼塊放在scripts之前,而不是附加在scripts之后:

head
  yield script(src='/jquery.js') script(src='/jquery.ui.js') 

由於被包含的Jade會按字面解析並合並到AST中,詞法范圍的變量的效果和直接寫在同一個文件中的相同。這就意味着include可以用作partial的替代,例如,假設我們有一個引用了user變量的user.jade`文件:

h1= user.name p= user.occupation 

接着,當我們迭代users的時候,只需簡單地加上include user。因為在循環中user變量已經被定義了,被包含的模板可以訪問它。

users = [{ name: 'Tobi', occupation: 'Ferret' }] each user in users .user include user 

以上代碼會生成:

<div class="user"> <h1>Tobi</h1> <p>Ferret</p> </div> 

user.jade引用了user變量,如果我們希望使用一個不同的變量user,那么我們可以直接定義一個新變量user = person,如下所示:

each person in users .user user = person include user 

Mixins

Mixins 在編譯的模板里會被 Jade 轉換為普通的 JavaScript 函數。 Mixins 可以帶參數,但不是必需的:

mixin list ul li foo li bar li baz 

使用不帶參數的 mixin 看上去非常簡單,在一個塊外:

h2 Groceries mixin list 

Mixins 也可以帶一個或者多個參數,參數就是普通的 JavaScript 表達式,比如下面的例子:

mixin pets(pets) ul.pets - each pet in pets li= pet mixin profile(user) .user h2= user.name mixin pets(user.pets) 

會輸出像下面的 HTML:

<div class="user"> <h2>tj</h2> <ul class="pets"> <li>tobi</li> <li>loki</li> <li>jane</li> <li>manny</li> </ul> </div> 

產生輸出

假設我們有下面的 Jade 源碼:

- var title = 'yay' h1.title #{title} p Just an example 

當 compileDebug 選項不是 false, Jade 會編譯時會把函數里加上 __.lineno = n;, 這個參數會在編譯出錯時傳遞給rethrow(), 而這個函數會在 Jade 初始輸出時給出一個有用的錯誤信息。

function anonymous(locals) { var __ = { lineno: 1, input: "- var title = 'yay'\nh1.title #{title}\np Just an example", filename: "testing/test.js" }; var rethrow = jade.rethrow; try { var attrs = jade.attrs, escape = jade.escape; var buf = []; with (locals || {}) { var interp; __.lineno = 1; var title = 'yay' __.lineno = 2; buf.push('<h1'); buf.push(attrs({ "class": ('title') })); buf.push('>'); buf.push('' + escape((interp = title) == null ? '' : interp) + ''); buf.push('</h1>'); __.lineno = 3; buf.push('<p>'); buf.push('Just an example'); buf.push('</p>'); } return buf.join(""); } catch (err) { rethrow(err, __.input, __.filename, __.lineno); } } 

當 compileDebug 參數是 false, 這個參數會被去掉,這樣對於輕量級的瀏覽器端模板是非常有用的。結合 Jade 的參數和當前源碼庫里的 ./runtime.js 文件,你可以通過 toString() 來編譯模板而不需要在瀏覽器端運行整個 Jade 庫,這樣可以提高性能,也可以減少載入的 JavaScript 數量。

function anonymous(locals) { var attrs = jade.attrs, escape = jade.escape; var buf = []; with (locals || {}) { var interp; var title = 'yay' buf.push('<h1'); buf.push(attrs({ "class": ('title') })); buf.push('>'); buf.push('' + escape((interp = title) == null ? '' : interp) + ''); buf.push('</h1>'); buf.push('<p>'); buf.push('Just an example'); buf.push('</p>'); } return buf.join(""); } 

Makefile 的一個例子

通過執行 make, 下面的 Makefile 例子可以把 pages/*.jade 編譯為 pages/*.html 。

JADE = $(shell find pages/*.jade) HTML = $(JADE:.jade=.html) all: $(HTML) %.html: %.jade jade < $< --path $< > $@ clean: rm -f $(HTML) .PHONY: clean 

這個可以和 watch(1) 命令起來產生像下面的行為:

$ watch make 

命令行的 Jade

 

使用: jade [options] [dir|file ...] 選項: -h, --help 輸出幫助信息 -v, --version 輸出版本號 -o, --out <dir> 輸出編譯后的 HTML 到 <dir> -O, --obj <str> JavaScript 選項 -p, --path <path> 在處理 stdio 時,查找包含文件時的查找路徑 -P, --pretty 格式化 HTML 輸出 -c, --client 編譯瀏覽器端可用的 runtime.js -D, --no-debug 關閉編譯的調試選項(函數會更小) -w, --watch 監視文件改變自動刷新編譯結果 Examples: # 編譯整個目錄 $ jade templates # 生成 {foo,bar}.html $ jade {foo,bar}.jade # 在標准IO下使用jade $ jade < my.jade > my.html # 在標准IO下使用jade, 同時指定用於查找包含的文件 $ jade < my.jade -p my.jade > my.html # 在標准IO下使用jade $ echo "h1 Jade!" | jade # foo, bar 目錄渲染到 /tmp $ jade foo bar --out /tmp

注意: 從 v0.31.0 的 -o 選項已經指向 --out-O 相應做了交換


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM