Node.js
Jade

Jadeの記法について(あまりまとまっていない)

More than 4 years have passed since last update.

Jadeの記法について(あまりまとまっていない)

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

タグの記述と構造化

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

in
div
  ul
    li い
    li ろ
    li は
out
<div>
  <ul>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>

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


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

in
footer: p: small Qiita
out
<footer>
  <p><small>Qiita</small></p>
</footer>

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

in
p
  | aaa
  | bbb
  | ccc

p.
  ddd
  eee
  fff
out
<p>
  aaa
  bbb
  ccc
</p>
<p>
  ddd
  eee
  fff
</p>

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

in
footer
  p <a href="//qiita.com/">Qiita</a>
out
<footer>
  <p><a href="//qiita.com/">Qiita</a></p>
</footer>

属性

丸括弧で囲う。

in
a(href="//google.com/", target="_blank") google.com
out
<a href="//google.com/" target="_blank">google.com</a>

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

in
a(href="//google.com/",
  target="_blank") google.com
a(
  href="//google.com/"
  target="_blank") google.com
out
<a href="//google.com/" target="_blank">google.com</a><a href="//google.com/" target="_blank">google.com</a>

classとid

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

in
h1#title.class1.class2 title
out
<h1 id="title" class="class1 class2">title</h1>

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

in
#frame
  .inline
out
<div id="frame">
  <div class="inline"></div>
</div>

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

- var classes = ['class1', 'class2', 'class3'];
div(class=classes)
div(data-class=classes)
out
<div class="class1 class2 class3"></div>
<div data-class='["class1","class2","class3"]'></div>

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

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
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>

単独タグ

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

in
special:tag(option="1")/
special:tag/(option="1")
out
<special:tag option="1"/>
<special:tag option="1"/>

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

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

JavaScriptでの制御

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

in
- for (var i = 0; i < 3; i++) {
  li list
- }
out
<li>list</li>
<li>list</li>
<li>list</li>
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}
- }
in
<p>a: 1</p>
<p>b: 2</p>
<p>c: 3</p>

DOCTYPE宣言

doctype xxxと記述する。

in
doctype
doctype html
doctype xml
doctype strict
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">

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

コメント

コメントは//で書く。

in
// コメントだよ

//
  コメント
  コメント
  コメント
out
<!-- コメントだよ-->
<!--
コメント
コメント
コメント
-->

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

in
//- 出力されない
div
out
<div></div>

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

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

直接書けということか。

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

変数展開

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

in
- var text = "<span>Qiita</span>";
p= text
p!= text
out
<p>&lt;span&gt;Qiita&lt;/span&gt;</p>
<p><span>Qiita</span></p>

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

in
- var text = "<span>Qiita</span>";
p #{text}:Team
p !{text}:Team
out
<p>&lt;span&gt;Qiita&lt;/span&gt;:Team</p>
<p><span>Qiita</span>:Team</p>

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


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

in
- var domain = 'google.com'
a(href="//#{domain}/") google
a(href="//" + domain + "/") google
out
<a href="//google.com/">google</a>
<a href="//google.com/">google</a>

フィルタ

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

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

in
body
  :markdown
    # h1

    Markdown filter
  footer
out
<body><h1 id="h1">h1</h1>
<p>Markdown filter</p>

  <footer></footer>
</body>

インクルード

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

_template.jade
p before
in
include _block
p _template
p after
out
<p>before</p>
<p>_template</p>
<p>after</p>

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

_block.html
<p>_block</p>
in
p before
include _block.html
p after
out
<p>before</p>
<p>_block</p>
<p>after</p>

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

_block.jade
yield
p 1
in
include _block
  p 0
out
<p>0</p>
<p>1</p>

データのバインド(?)もできる。

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

each twitter in twitterData
  include twitter
out
<p>sasaplus1</p>
<p>JavaScript, node.js, Bash, Delphi</p>

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

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

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

text.txt
# h1
## h2
in
p before
include:markdown text.txt
p after
out
<p>before</p>
<h1>h1</h1>
<h2>h2</h2>
<p>after</p>

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

text.md
# h1
in
p before
include text.md
p after
out
<p>before</p>
# h1
<p>after</p>

ブロック

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

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

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

append/prepend

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

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

prepend content
  #prepend 前に挿入される

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

mixin

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

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!")
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の代わりに+が使用できる。

in
mixin title-block(title)
  h1= title

+title-block("Hello, World!")
out
<h1>Hello, World!</h1>

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

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

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

+title-block#special-id.class1.class2.class3
out
<div id="special-id" class="class1 class2 class3">
  <p>Qiita</p>
</div>

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

mixin title-block#special-id.class1.class2.class3
out
<div>
  <p>Qiita</p>
</div>
<div id="special-id" class="class1 class2 class3"></div>

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

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/")
out
<div id="frame-google" class="frame"><a href="//google.com/" title="Google">google</a></div>

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

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)
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もしくはunlesselseで条件分岐ができる。

in
- var flag = true;

if flag
  p trueです
else
  p falseです
in
<p>trueです</p>
in
- var flag = true;

unless flag
  p trueです
else
  p falseです
out
<p>falseです</p>

else ifも使用できる。

in
- var flag = 1

if flag === 0
  p 0です
else if flag === 1
  p 1です
else
  p 0でも1でもありません
out
<p>1です</p>

case-when

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

in
- var flag = 1

case flag
  when 0
    p 0です
  when 1
    p 1です
  default
    p 0でも1でもありません
<p>1です</p>

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

in
- var flag = 2

case flag
  when 0:    p 0です
  when 1, 2: p 1か2です
  when 3:    p 3です
out
<p>1か2です</p>

while

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

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でも動作は同じ。

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

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

参考