こんにちは、ryosukeです。
ラボブログの前々回のエントリーで ruby で実装された web application framework の Sinatra が紹介されていたのですが、私もあまりのお手頃感に触発されて少しさわってみました。
その時にふとモデルやビューにいつもは使わない物を使ってみようと思い立ち、 Sequel と Haml を選んでみたのですが、 Haml の構文が見た目に反して(?)思いの他わかりやすかったので、今更感もありますが私同様 erb 以外使おうとも思わなかった人も少なくないのでは無いかと思いご紹介させて頂こうと思います。
Haml は XHTML Abstraction Markup Language の略で...という所から説明するのが筋なのですが、あっという間に5分経過してしまいそうなので、要点をかいつまんで進めて行こうと思います。
まずは簡単に全体像を見る
以下のようにマークアップします。
Haml
!!! XML !!! %html %head %meta{ 'http-equiv' => 'content', :content => 'text/html; charset=utf-8'} %body %div#container %a welcome to | labs.unoh.net |
出力
<?xml version='1.0' encoding='utf-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta content='text/html; charset=utf-8' http-equiv='content' /> </head> <body> <div id='container'> <a>welcome to labs.unoh.net</a> </div> </body> </html>
XML宣言
!!! XML
<?xml version='1.0' encoding='utf-8' ?>
MEMO: 第二引数に文字コードを指定できる。デフォルトはUTF-8。
!!! XML euc-jp
<?xml version='1.0' encoding='euc-jp' ?>
文書型宣言
!!!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
MEMO: デフォルトでは XHTML 1.0 Transitional になります。他にもいくつか例示すると以下のように記述できます。
!!! Strict
!!! Frameset
!!! 1.1
%要素名
%a labs.unoh.net
<a>labs.unoh.net</a>
MEMO: 要素名を省略できる場面では DIV がデフォルトになる。
%要素名{:属性名 => '値'}
%a{:href => 'http://labs.unoh.net/'} labs.unoh.net
<a href="http://unoh.github.com/">labs.unoh.net</a>
MEMO: %aと{}の間にスペースを空けない。シンボルに使えない文字を含めたい場合(http-equivの-等)は文字列にする。
要素のネスト
%div %a{:href => 'http://labs.unoh.net/'} labs.unoh.net
<div> <a href='http://labs.unoh.net/'>labs.unoh.net</a> </div>
MEMO: ネストはインデントで表現する。 1インデントは2つのスペースで表現する。
複数行分割
%span この行は長過ぎるので行分割したい | パイプで行分割できるんです。 |
<span>この行は長過ぎるので行分割したい パイプで行分割できるんです。</span>
これはテキストだけでなく、構文中に含める事が出来ます。
%script{ :type => "textjavascript", | :src => "/js/jquery.js" } |
MEMO: |の前にスペースが必須。最終行の |を忘れないように。
コメント
/ HTMLのコメント
<!-- HTMLのコメント -->
-# haml のコメント
出力ドキュメントとしては表示されません
エスケープ
Hamlに取って意味のあるメタ文字をエスケープするには ¥ を使います。
¥%a が <a>になります
%a が <a>になります
ID
id は属性の一つなので {} で表現する事も可能ですが、 id と class は以下の様なショートカット構文が用意されています。
%div#container body
<div id='container'>body</div>
%div.navi menu
<div class='navi'>menu</div>
フィルター
:(コロン)+キーワードでインデントされたブロックにフィルタをかける事が出来ます。
フィルタは他にもいくつか用意されているので、マニュアルを見てください。
javascript
%head :javascript var string = 'hello'; window.alert(string);
<head> <script type='text/javascript'> //<![CDATA[ var string = 'hello'; window.alert(string); //]]> </script> </head>
escaped
%div :escaped <html> <head> <title>title</title> </head> <body> <h1>h1</h1> </body> </html>
<div> <html> <head> <title>title</title> </head> <body> <h1>H1</h1> </body> </html> </div>
rubyコードを埋め込む
= 以降に ruby コードを書くと、評価して出力してくれます。
%div= "現在の時刻は" + Time.now.to_s + "です"
<div>現在の時刻はTue May 26 17:28:15 +0900 2009です</div>
制御構文
制御構文と題しましたが実際には ruby コードがかけます。 = との違いは評価結果を出力するか否かで、こちらは出力しないのでテンプレートとして使う場合は制御構文を書く場合が多いでしょう。
- (1..10).each do |i| %p= "値は#{i}です。" - if i >= 5 %span.big 5以上
<p>値は1です。</p> <p>値は2です。</p> <p>値は3です。</p> <p>値は4です。</p> <p>値は5です。</p> <span class='big'>5以上</span> <p>値は6です。</p> <span class='big'>5以上</span> <p>値は7です。</p> <span class='big'>5以上</span> <p>値は8です。</p> <span class='big'>5以上</span> <p>値は9です。</p> <span class='big'>5以上</span> <p>値は10です。</p> <span class='big'>5以上</span>
いかがでしょうか?5分だと少しきついかもしれませんが、これを見ただけでもすぐ書けそうな気がしませんか?
ここまで Haml の基本的な構文をかいつまんでみてきましたが、できるだけ出力に近い方が何かと便利というのは正直な所で、プロダクションレベルや共同作業が必要になる場合に採用するかというとちょっと...と考えてしまうかも知れません。とはいえ HTML を理解していればとても簡単に Haml も覚える事ができるので、どんな物かを知る為にちょっと触ってみるのも良いのではないでしょうか。
また、 Haml には Sass という CSS テンプレートがあり、簡潔に記述したり、変数を使ったり、コードを再利用したり、出力されるCSSを圧縮したりと erb等のテンプレートシステム を使って CSS をメンテナンスした事がある人にとっては恐らく Haml 以上に魅力的なおすすめツールだと思います。今回 Sass は扱いませんでしたが、機会があれば Sass にも触れられればと思います。