Jadeの記法について（あまりまとまっていない）

# Jadeの記法について（あまりまとまっていない）

- node.js ver.0.10.24
- npm ver.1.3.21
- Jade ver 1.1.4

## タグの記述と構造化

タグ名を書いて、インデントで構造を表す。

```jade:in
div
  ul
    li い
    li ろ
    li は
```

```html:out
<div>
  <ul>
    <li>い</li>
    <li>ろ</li>
    <li>は</li>
  </ul>
</div>
```

インデントには半角スペースかタブが使用できる。が、両方を使うとコンパイルできずにエラーになる。

---

`:`を使用するとインデントせずに、同じ行に再度タグを記述できる。

```jade:in
footer: p: small Qiita
```

```html:out
<footer>
  <p><small>Qiita</small></p>
</footer>
```

---

テキストを複数行記述する場合、`|`か`.`を使用する。

```jade:in
p
  | aaa
  | bbb
  | ccc

p.
  ddd
  eee
  fff
```

```html:out
<p>
  aaa
  bbb
  ccc
</p>
<p>
  ddd
  eee
  fff
</p>
```

---

直にHTMLを書くこともできる。

```jade:in
footer
  p <a href="//qiita.com/">Qiita</a>
```

```html:out
<footer>
  <p><a href="//qiita.com/">Qiita</a></p>
</footer>
```

### 属性

丸括弧で囲う。

```jade:in
a(href="//google.com/", target="_blank") google.com
```

```html:out
<a href="//google.com/" target="_blank">google.com</a>
```

---

属性を改行して書くこともでき、コンマも省略できる。

```jade:in
a(href="//google.com/",
  target="_blank") google.com
a(
  href="//google.com/"
  target="_blank") google.com
```

```html:out
<a href="//google.com/" target="_blank">google.com</a><a href="//google.com/" target="_blank">google.com</a>
```

### classとid

classを付加するにはタグ名の後に`.`を、idを付加するにはタグ名の後に`#`を書き、それの名前を書く。

```jade:in
h1#title.class1.class2 title
```

```html:out
<h1 id="title" class="class1 class2">title</h1>
```

---

タグ名を省略して記述した場合は、`div`タグにclassもしくはidが付与されて出力される。

```jade:in
#frame
  .inline
```

```html:out
<div id="frame">
  <div class="inline"></div>
</div>
```

---

class属性のみ、配列をそのまま受け取れる。

```jade
- var classes = ['class1', 'class2', 'class3'];
div(class=classes)
div(data-class=classes)
```

```html:out
<div class="class1 class2 class3"></div>
<div data-class='["class1","class2","class3"]'></div>
```

---

`false`や`null`、`undefined`もしくは定義されていない変数が属性に指定された場合、出力されない。

```jade:in
a(href="//google.com/", title=false) google
a(href="//google.com/", title=null) google
a(href="//google.com/", title=undefined) google
a(href="//google.com/", title=unknown) google
a(href="//google.com/", title=(typeof unknown !== 'undefined')) google
```

```html:out
<a href="//google.com/">google</a>
<a href="//google.com/">google</a>
<a href="//google.com/">google</a>
<a href="//google.com/">google</a>
<a href="//google.com/">google</a>
```

### 単独タグ

独自の単独タグを記述する場合は、タグ名の最後に`/`を書く。

```jade:in
special:tag(option="1")/
special:tag/(option="1")
```

```html:out
<special:tag option="1"/>
<special:tag option="1"/>
```

どちらも同じ出力になるが、vim-jadeだと後者は属性が強調表示されなくなるため前者の方が良いか？

`br`や`hr`などは自動で単独タグ扱いされるため、`/`を書く必要はない。

- [jade/lib/self-closing.js](https://github.com/visionmedia/jade/blob/96a6b0a9057534fc02c86f1c84e1cdd1a54602c2/lib/self-closing.js)

## JavaScriptでの制御

`-`で直接JavaScriptを書くことが出来る。

```jade:in
- for (var i = 0; i < 3; i++) {
  li list
- }
```

```html:out
<li>list</li>
<li>list</li>
<li>list</li>
```

```jade:in
- var objs = [];
- objs.push({name: "a", value: "1"});
- objs.push({name: "b", value: "2"});
- objs.push({name: "c", value: "3"});
- for (var i = 0; i < objs.length; i++) {
  p #{objs[i].name}: #{objs[i].value}
- }
```

```html:in
<p>a: 1</p>
<p>b: 2</p>
<p>c: 3</p>
```

## DOCTYPE宣言

`doctype xxx`と記述する。

```jade:in
doctype
doctype html
doctype xml
doctype strict
```

```html:out
<!DOCTYPE html>
<!DOCTYPE html>
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
```

- [jade/lib/doctype.js](https://github.com/visionmedia/jade/blob/96a6b0a9057534fc02c86f1c84e1cdd1a54602c2/lib/doctypes.js)

以前使用できた、`!!! 5`や`doctype 5`はコンパイルできずにエラーになる。

## コメント

コメントは`//`で書く。

```jade:in
// コメントだよ

//
  コメント
  コメント
  コメント
```

```html:out

<!-- コメントだよ-->
<!--
コメント
コメント
コメント
-->
```

---

HTMLに出力しないコメントを記述する場合は`//-`を使用する。

```jade:in
//- 出力されない
div
```

```html:out
<div></div>
```

---

条件付きコメントの機能は削除された？

```jade:in
//if lt IE 8
  script(src="http://ajax.aspnetcdn.com/ajax/modernizr/modernizr-2.7.1.js")
```

```html:out
<!--if lt IE 8script(src="http://ajax.aspnetcdn.com/ajax/modernizr/modernizr-2.7.1.js")
-->
```

- [Conditional Comments](https://github.com/visionmedia/jade/issues/1345)

直接書けということか。

```jade:in
<!--[if lt IE 8]>
script(src="http://ajax.aspnetcdn.com/ajax/modernizr/modernizr-2.7.1.js")
<![endif]-->
```

```html:out
<!--[if lt IE 8]>
<script src="http://ajax.aspnetcdn.com/ajax/modernizr/modernizr-2.7.1.js"></script><![endif]-->
```

## 変数展開

タグ名のあとに`=`もしくは`!=`でそのまま変数を展開できる。`!=`の場合はエスケープされない。

```jade:in
- var text = "<span>Qiita</span>";
p= text
p!= text
```

```html:out
<p>&lt;span&gt;Qiita&lt;/span&gt;</p>
<p><span>Qiita</span></p>
```

---

文字列中に展開したい場合は`#{}`もしくは`!{}`を使用すると展開できる。`!{}`の場合はエスケープされない。

```jade:in
- var text = "<span>Qiita</span>";
p #{text}:Team
p !{text}:Team
```

```html:out
<p>&lt;span&gt;Qiita&lt;/span&gt;:Team</p>
<p><span>Qiita</span>:Team</p>
```

そのままJavaScriptの式が書けるので変数展開、というよりかは式展開か。

---

式がそのまま書けるので、展開せずとも`+`でそのまま連結するなどの方法もある。

```jade:in
- var domain = 'google.com'
a(href="//#{domain}/") google
a(href="//" + domain + "/") google
```

```html:out
<a href="//google.com/">google</a>
<a href="//google.com/">google</a>
```

## フィルタ

`:`につづいて`markdown`などと記述すると、そのブロックではJade以外の記法で記述することが出来る。

Markdownフィルタを使用する場合は`marked`などのモジュールがインストールされている必要がある。

```jade:in
body
  :markdown
    # h1

    Markdown filter
  footer
```

```html:out
<body><h1 id="h1">h1</h1>
<p>Markdown filter</p>

  <footer></footer>
</body>
```

## インクルード

`include ファイル名`で他のファイルを挿入することができる。拡張子を省略した場合は`ファイル名.jade`と見なしてそのファイルを読み込みに行く。

```jade:_template.jade
p before
```

```jade:in
include _block
p _template
p after
```

```html:out
<p>before</p>
<p>_template</p>
<p>after</p>
```

---

HTMLをそのまま挿入することもできる。

```html:_block.html
<p>_block</p>
```

```jade:in
p before
include _block.html
p after
```

```html:out
<p>before</p>
<p>_block</p>
<p>after</p>
```

---

`yield`と書いておくと間にコンテンツを挿入することができる。

```jade:_block.jade
yield
p 1
```

```jade:in
include _block
  p 0
```

```html:out
<p>0</p>
<p>1</p>
```

---

データのバインド（？）もできる。

```jade:twitter.jade
p= twitter.name
p= twitter.description
```

```jade:in
- var twitterData = [{name: "sasaplus1", description: "JavaScript, node.js, Bash, Delphi"}];

each twitter in twitterData
  include twitter
```

```html:out
<p>sasaplus1</p>
<p>JavaScript, node.js, Bash, Delphi</p>
```

### フィルタ付きインクルード

`include`の後に`:フィルタ名`を記述すると、ファイルをフィルタで変換したものを挿入できる。

この場合も適用したいフィルタのモジュールがインストールされている必要がある。

```markdown:text.txt
# h1
## h2
```

```jade:in
p before
include:markdown text.txt
p after
```

```html:out
<p>before</p>
<h1>h1</h1>
<h2>h2</h2>
<p>after</p>
```

---

拡張子の自動判別は無くなった？

```markdown:text.md
# h1
```

```jade:in
p before
include text.md
p after
```

```html:out
<p>before</p>
# h1
<p>after</p>
```

---

## ブロック

インクルードされるファイルに`block ブロック名`を記述し、インクルードする側で`include`でなく`extends`で読み込んだあと同じブロック名で異なる内容を書くと、ブロックの内容を上書きできる。

```jade:_block.jade
header ヘッダ
block content
  p コンテンツ
footer フッタ
```

```jade:in
extends _block

block content
  #content Qiitaだよー
```

```html:out
<header>ヘッダ</header>
<div id="content">Qiitaだよー</div>
<footer>フッタ</footer>
```

### append/prepend

`block`でなく`prepend`とすると指定したブロックの前に挿入でき、`append`とすると指定したブロックの後に挿入できる。

```jade:_block.jade
header ヘッダ
block content
  p コンテンツ
footer フッタ
```

```jade:in
extends _block

prepend content
  #prepend 前に挿入される

append content
  #append 後ろに挿入される
```

```html:out
<header>ヘッダ</header>
<div id="prepend">前に挿入される</div>
<p>コンテンツ</p>
<div id="append">後ろに挿入される</div>
<footer>フッタ</footer>
```

## mixin

`mixin`で関数のような形でブロックを生成できる。

```jade:in
mixin title-block(title, date)
  h1= title
  p= date || new Date

mixin title-block("Hello, World!", "Tue Jan 14 2014 00:00:00 GMT+0900 (JST)")
mixin title-block("Hello, World!")
```

```html:out
<h1>Hello, World!</h1>
<p>Tue Jan 14 2014 00:00:00 GMT+0900 (JST)</p>
<h1>Hello, World!</h1>
<p>Tue Jan 14 2014 00:12:39 GMT+0900 (JST)</p>
```

---

展開する際は`mixin`の代わりに`+`が使用できる。

```jade:in
mixin title-block(title)
  h1= title

+title-block("Hello, World!")
```

```html:out
<h1>Hello, World!</h1>
```

---

`attributes`でclass/idや属性を受け取ることができる。（あまり良くわかっていない）

`+`を使用した場合と`mixin`を使用した場合で挙動が異なるのだが……

```jade:in
mixin title-block
  div(id=attributes.id, class=attributes.class)
    p Qiita

+title-block#special-id.class1.class2.class3
```

```html:out
<div id="special-id" class="class1 class2 class3">
  <p>Qiita</p>
</div>
```

---

```jade:in
mixin title-block
  div(id=attributes.id, class=attributes.class)
    p Qiita

mixin title-block#special-id.class1.class2.class3
```

```html:out
<div>
  <p>Qiita</p>
</div>
<div id="special-id" class="class1 class2 class3"></div>
```

---

`attributes`と引数との違いがあまりよくわかっていない。どういう風に使い分けるのか。

```jade:in
mixin content(text)
  div(id=attributes.id, class=attributes.class)
    a(href=attributes.href, title=attributes.title)= text

+content("google")#frame-google.frame(title="Google", href="//google.com/")
```

```html:out
<div id="frame-google" class="frame"><a href="//google.com/" title="Google">google</a></div>
```

---

`mixin`内では`arguments`も使用できる。

```jade:in
mixin title-block
  ul
    - for (var i = 0; i < arguments.length; i++) {
      li= arguments[i]
    - }

mixin title-block(1)
mixin title-block(1, 2)
mixin title-block(1, 2, 3)
```

```html:out
<ul>
  <li>1</li>
</ul>
<ul>
  <li>1</li>
  <li>2</li>
</ul>
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>
```

## if/unless

`if`もしくは`unless`や`else`で条件分岐ができる。

```jade:in
- var flag = true;

if flag
  p trueです
else
  p falseです
```

```html:in
<p>trueです</p>
```

```jade:in
- var flag = true;

unless flag
  p trueです
else
  p falseです
```

```html:out
<p>falseです</p>
```

---

`else if`も使用できる。

```jade:in
- var flag = 1

if flag === 0
  p 0です
else if flag === 1
  p 1です
else
  p 0でも1でもありません
```

```html:out
<p>1です</p>
```

## case-when

`case`でも条件分岐ができる。条件は`when`の後に記述し、どれにも当てはまらない場合は`default`を書く。

```jade:in
- var flag = 1

case flag
  when 0
    p 0です
  when 1
    p 1です
  default
    p 0でも1でもありません
```

```
<p>1です</p>
```

---

`when 値`のあとに`:`を記述することで、一行で書くことができる。また、条件の値は`,`で複数の値を指定できる。

```jade:in
- var flag = 2

case flag
  when 0:    p 0です
  when 1, 2: p 1か2です
  when 3:    p 3です
```

```html:out
<p>1か2です</p>
```

## while

`while`で繰り返しを記述できる。

```jade:in
- var i = 3

while i--
  p= i
```

```
<p>2</p>
<p>1</p>
<p>0</p>
```

## for-in, each-in

`for-in`または`each-in`でも繰り返しが記述できる。`for`でも`each`でも動作は同じ。

ループでは変数の値と、変数がオブジェクトの場合はキーを、変数が配列の場合はインデックスが取得できる。キー、もしくはインデックスが必要ない場合は変数名の記述を省略できる。

```jade:in
ul
  for val, index in ['a', 'b', 'c']
    li #{index}: #{val}

ul
  each val, key in {key1: 'a', key2: 'b', key3: 'c'}
    li #{key}: #{val}
```

```html:out
<ul>
  <li>0: a</li>
  <li>1: b</li>
  <li>2: c</li>
</ul>
<ul>
  <li>key1: a</li>
  <li>key2: b</li>
  <li>key3: c</li>
</ul>
```

## 参考

- http://jade-lang.com/
- https://github.com/visionmedia/jade/blob/96a6b0a9057534fc02c86f1c84e1cdd1a54602c2/jade.md
- https://github.com/visionmedia/jade/blob/96a6b0a9057534fc02c86f1c84e1cdd1a54602c2/jade-language.md
- http://nextdeveloper.hatenablog.com/entry/2013/12/10/180457
- http://blog.craftgear.net/4f501e97c1347ec934000001/title/10%E5%88%86%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8Bjade%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%B3
- http://blog.kazupon.jp/post/19007475354/jade-template-inheritance
- http://blog.kazupon.jp/post/38877362879/jade-mixin-tips
- http://rtshaaaa.hateblo.jp/entry/2013/12/20/133054
- https://gist.github.com/kazupon/4379815