CTC 教育サービス
[IT研修]注目キーワード Python UiPath(RPA) 最新技術動向 Microsoft Azure Docker Kubernetes
こんにちは。 藺藤です。
今回のRuby & Railsコラムでは「altERBで楽々Railsコーディング」と題し、Railsでも利用できるGemの一つ、「Haml」を紹介します。(*1) Hamlは簡潔な記述でHTMLを作成できるテンプレートエンジンです。
Hamlの説明に入る前に、RailsでビューのHTMLを作成するときにデフォルトで利用するERBを見てみましょう。(*2)
ERBはRuby製テンプレートエンジンです。 HTMLに限らず、様々なテキストファイル中にRubyコードを埋め込みたいときに利用されます。 ERBファイルの拡張子は.erbです。 例えば、挨拶するHTMLを作成する場合には次のように書きます。(*3)
[greeting.html.erb] <div id="message"><%= "こんにちは。" %></div> [greeting.html] <div id="message">こんにちは。</div>
この例を応用させて、現在時刻に応じて「おはようございます」「こんばんは」等と挨拶させることもできます。
ERBを利用することで、Webページにアクセスした時点でのデータベースの値や、ユーザの入力に基づいた計算結果などを含む、いわゆる動的なページを作成することができます。 ERB自体はプログラマにとって馴染み易く、取り組みやすいものです。 類似の技術としてPHP言語や、Java言語のJSPが挙げられます。
ERBは便利なものですが、汎用的なテンプレートエンジンであるため、HTMLを書き下すことを目的とする場合には冗長な記述になりがちです。 このような場合、専用のテンプレートエンジンを利用することでHTMLを「より簡潔に記述し」、「より素早くコーディングできる」ようになります。
今回はRailsのERBを代替できるテンプレートエンジン(="altERB")として「Haml」を紹介します。 Hamlを使うと、上で示した挨拶の例は次のように書き下せます。 なお、Hamlの拡張子は.hamlです。
[greeting.html.haml] #message こんにちは。 [greeting.html] <div id="message">こんにちは。</div>
Hamlの詳しい書き方はこの後で紹介しますが、ここでは「erbと比べてソースコードが非常に短くなった」ことに注目してください。 実際に文字数を数えてみると
と、長さは実に半分以下になりました。(ここでは半角・全角文字、スペースいずれも1文字と数えています。)
Hamlでは、閉じタグを書く必要がありません。 また、利用頻度の高い、idやclassの指定に関してはCSSと同様に「#」や「.」で指定することができます。 このようなHamlの記述ルールによって、プログラマは非常にすっきりとコーディングすることができます。
Hamlを導入するためには、端末を開いて以下のコマンドを実行してください。
$ gem install haml
無事にインストールされたでしょうか。 動作確認しましょう。
初めに、新しいファイルgreeting.html.hamlを作成します。 内容は上の例と同じものにしてください。 HamlをHTMLにコンパイルするには、hamlコマンドを実行します。
[greeting.html.haml] #message こんにちは。 $ haml greeting.html.haml #=> <div id="message">こんにちは。</div>
このように、コンパイル結果のHTMLが表示されていれば成功です。 変換結果をファイルに書き出したい場合には、hamlコマンドに「入力ファイル」「出力ファイル」の順で指定してください。
$ haml greeting.html.haml greeting.html
作成されたHTMLファイルgreeting.htmlをブラウザで確認してください。
Hamlコマンドで利用できるオプションを調べたい場合、「-h」オプションが利用できます。
$ haml -h
「-v」オプションを利用し、インストール済みのHamlのバージョンを確認しておきます。
$ haml -v #=> Haml 4.0.7
筆者が利用しているのは、Haml バージョン4.0.7のようです。
今回のコラムは、以下に記すような筆者の手元の環境で動作確認しています。
さて、ここまでは文法を一切説明しないまま、とりあえずHamlを使ってきました。 ここからは文法を説明します。 ぜひ、実際に入力・出力をしながら読み進めてください。(コマンドの実行は省略します。)
HTMLタグを記述するためには「%」記号を利用し、タグの名前を指定します。 また、タグの名前の後ろに半角スペースを1文字入れると、続く部分はタグの内容として解釈されます。
%h3 タグの記述「%tag content」 %p これはpタグです #=> <h3>タグの記述「%tag cotent」</h3> #=> <p>これはpタグです</p>
%tagに続けてRubyのHash形式で属性を指定できます。 例として、idを指定する場合は次のように書けます。
%p{id: "explanation-attr"} 属性の指定「{attr1: value1, attr2: value2, ... }」 #=> <p id="explanation-attr">属性の指定「{attr1: value1, attr2: value2, ... }」
この形式を利用することでhrefやaltなど、任意の属性を指定できます。
idやclassの指定は利用頻度が高いと考えられることから、Hamlではこれらの指定に関して特別な記法を認めています。 idの指定には「#」記号、また、classの指定には「.」記号を利用します。 "特別な記法"と言っても、CSSでお馴染みの記法ですね。
%div#my-id.my_class id、classの指定「#」「.」 #=> <div class="my_class" id="my-id">id、classの指定「#」「.」</div>
また、divタグは頻繁に利用するため省略形が認められています。 上のHamlコードは次のように書き換えることができます。
#my-id.my_class id、classの指定「#」「.」 #=> <div class="my_class" id="my-id">id、classの指定「#」「.」</div>
先頭に「%」記号が存在せず、idやclassの指定(「#」や「.」)がある場合には、%divを省略したものとして扱われます。
複数のタグの入れ子構造を作りたい場合、Hamlではインデントによって入れ子の親・子を表現します。 また、インデントの深さが元に戻った場合にはタグの終了を意味します。
実際にコードを見てみましょう。
#parent 親 #child 子 #grandchild 孫 #=> <div id="parent"> #=> 親 #=> <div id="child"> #=> 子 #=> <div id="grandchild">孫</div> #=> </div> #=> </div>
インデントの深さは何文字でもよいですが、ここではRubyで標準的な2文字分のインデントを採用しました。
要素の入れ子に関しては、ついやってしまいがちな注意点がありますので、ここで指摘しておきます。
(1) 子を持つタグに対し、「タグの内容」を書くことはできない
次のような書き方はできません。 「Illegal nesting(不正なネスト)」エラーが発生します。
#parent親 #child子 #grandchild 孫 #=> Illegal nesting: content can"t be both given on the same line as %div and nested within it.
#parent は子要素#childを持つにもかかわらず、#parentに続いてタグの内容("親"というテキスト)を記述してしまっています。
HTMLで考えると#parentは複数の子要素("親"というテキストと、idがchildのdivタグ)を持っています。 Hamlでは、これらは対等に扱わないといけません。 先に示したように、インデントを一つ下げて、同じレベルに全ての子要素を併記します。
(2) テキストに対して、子要素を持たせることはできない
急いでコーディングしていると、うっかり次のようなコードを書いてしまうかもしれません。 このときにも「Illegal nesting」エラーが発生します。
#parent 親 #child 子 #grandchild 孫 #=> Illegal nesting: nesting within plain text is illegal.
この場合、インデントが適切でないため、「テキスト"子"に対して子要素#grandchildを追加する」ものと解釈されてしまいます。 これは、HTMLで考えてみると当たり前ですが、不適切な構文です。
Hamlで、Rubyコードを実行する2つの構文を紹介します。
(1) コードを実行する「-」
半角のハイフンから始まる行は「Rubyコードが実行される」ものとして扱われます。 この部分には文法的に正しいRubyコードを記述する必要があります。
初めに、繰り返し処理の例を見てみましょう。
- 3.times do |i| こんにちは #=> こんにちは #=> こんにちは #=> こんにちは
Integer#timesメソッドを利用して、「こんにちは」を3回表示させました。
Rubyコードを実行させるときのポイントは
の3つです。 インデントや、endは不要であることを忘れないようにしてください。
条件分岐構文も同様です。 別の例を見てみます。
- r = rand(2) - if r.odd? おはようございます - else おやすみなさい #=> おやすみなさい # ※結果はランダムです。
この例は乱数を利用しているため結果はランダムですが、条件分岐により「おはようございます」または「おやすみなさい」のどちからが表示されます。
(2) 値を出力する「=」
半角の「=(イコール)」を利用して、Rubyコードの評価値を出力できます。 これはERBに似ていて、直感的な記法ではないでしょうか。
- 3.times do |i| = "#{i}回目の評価値" #=> 0回目の評価値 #=> 1回目の評価値 #=> 2回目の評価値
「-」や「=」の右辺はRubyとして正しい文法である必要があるため、出力文字列を""(クォーテーション)で囲っています。 この例では3回繰り返し、何回目の繰り返しであるのかを表示させています。
これはHamlの構文というよりもRubyの構文そのものですが、コメントも利用できます。
例を示します。
- # ここにコメント可能 - 3.times do |i| # ここにもコメントできる = "#{i}回目の評価値" # こんなところにもコメントできる
当然ながら、これらはただのコメントですので実行結果は変わりません。 Rubyコード部分のコメントは、HTMLコメントとは異なり、実行結果のHTMLには含まれません。
文法に関しては以上です。 ここまで紹介したものだけでも、HTMLの作成をかなり省力化できます。 ぜひお試しください。
Hamlの応用的な利用方法に関しては、本家リファレンス(英語)が参考になります。(*4)基本文法をマスターしたのち、リファレンスの方もご覧ください。
最後に、RailsでHamlを利用する方法について述べます。
Hamlの導入にあたっての注意ですが、1つのRailsアプリケーション上で、ERBファイルとHamlファイルを共存させることができます。 これはファイルの拡張子(.erbか、.hamlか)に従ってRailsが判断し、適切にコンパイルしているためです。
このため、アプリケーション開発の途中からHamlを導入した場合でも、既存のerbファイルを全て書き換える必要はありません。 まずは小さく始めることができます。 もちろん、望むならばすべてのERBファイルをHamlで書き換えることも可能です。(この場合は拡張子を手動で変更してください。)
RailsでHamlを利用できるようにするために、'haml-rails'を利用します。(*5) まず、Gemfileに以下を追加します。
[Gemfile] gem 'haml-rails'
いつも通り、bundle installを実行してください。
$ bundle install #=> Installing haml 4.0.7 #=> Installing haml-rails 0.9.0
Hamlが無事にインストールされました。(実行結果は一部抜粋しています。)
それでは適当にScaffoldしてみましょう。 コントローラやモデルはいつもの通りですが、ビューのファイルが「.html.erb」ではなく「.html.haml」で作成されています。
$ rails g scaffold test #=> invoke haml #=> create app/views/tests #=> create app/views/tests/index.html.haml #=> create app/views/tests/edit.html.haml #=> create app/views/tests/show.html.haml #=> ...
Scaffoldができたら、いずれかのHamlファイルをエディタで開いてみてください。 Railsジェネレータで作成されたファイルも、Hamlの文法を使ったものに改められていることを確認できます。
あとは先ほど説明したHamlの文法を使ってHamlファイルを編集してゆきます。
参考までに、Scaffold機能を使って「test」リソースをERB、Hamlそれぞれの場合で作成してみました。 2つの場合でindexビューの行数、文字数をカウントしてみると、
とhamlの方が2割ほど圧縮されています。
動的な部分(Rubyコード)が増えると、Hamlによる圧縮率は下がってしまいます。 一方、レイアウトのためのdivタグ等、静的な部分が増えると、より一層Hamlによる圧縮の恩恵が大きなものになります。
こちらのブログ(*6)では、「Scaffoldによって作成されたERBファイルをSlimに書き換える」といったことをしています。 この記事も参考になるのではないでしょうか。
今回は「altERBで楽々Railsコーディング」と題し、HTMLテンプレートエンジン「Haml」を紹介しました。
Hamlを利用すると簡潔な記述でHTMLを作成できるため、ソースコードがどんどん複雑化してゆく事態を軽減できます。 行数・文字数共に大きさを抑えられるため、ソースコードが全体的に短く、見やすいものになります。
行数・文字数を圧縮できることも魅力的ですが、筆者としては、
の2点が便利だと感じます。 ここには全文を示しませんが、RailsのScaffold機能を利用して
の2つを作成し、実際に比較してみてほしいと思います。 きっと、筆者の感じた2つの魅力を実感していただけるものと思います。 ぜひ、Hamlを活用してみてください。
さて、少しだけ次回の宣伝ですが、次回はHaml同様にRailsコーディングを楽にしてくれるテンプレートエンジン「Slim」をご紹介したいと思います。 次回のコラムもお楽しみに。
それでは、Enjoy Ruby!
*1 : 「Haml」の本家サイト。(英語) チュートリアルやリファレンスもありますので、ぜひ一読ください。
http://haml.info/
*2 : ERBについてはこちらの記事を参照のこと。
http://magazine.rubyist.net/?0017-BundledLibraries
*3 : ERBはコマンドラインからも実行できます。 次のコマンドを実行すると、コンパイルされた結果を表示できます。
$ erb greeting.html.erb
*4 : 「Haml」のリファレンス。(英語) Hamlがかなり詳細に説明されています。
http://haml.info/docs/yardoc/file.REFERENCE.html
*5 : 「Haml-rails」のGitHubページ。(英語) 既存のERBファイルをHamlに変換する方法も記されているなど有益です。
https://github.com/indirect/haml-rails
*6 : 参考にさせていただきました。
http://ruby-rails.hatenadiary.com/entry/20141001/1412097051
*7 : 本コラム執筆にあたり、参考にさせていただきました。
「Hamlの書き方」:
http://qiita.com/watak676/items/525ad3d8a1297e3244e3
「Hamlが5分で分るチートシート[Rails初心者チュートリアル]」
http://morizyun.github.io/blog/beginner-rails-tutorial-haml/
[IT研修]注目キーワード Python UiPath(RPA) 最新技術動向 Microsoft Azure Docker Kubernetes