Play 2.0でBootstrap 2.0対応

Play2.0Bootstrap2.0を使う方法を紹介します。

Play2.0ではパッケージviews.html.helper.twitterBootstrapにBootstrap用のテンプレートがあるのでこれ使えばいいじゃんと思っていたのですが、残念ながらこれはBootstrapの2.0には対応していません。見てみたら簡単に対応出来そうなので、このコードを参考に作ってみました。

Form Template Helpers

と、その前に、Play2.0のテンプレートについて少し紹介します。Play2.0にはForm周りのコーディングを楽にする為のform template helpersという仕組みが提供されています。このテンプレートで入力フィールドは

<input type="text" name="username" id="username" value="@user.name">

※@から始まる記述が動的に評価されます

こんなふうに直接書くことも出来るのですが、このhelpersを使うと

@helper.inputText(myForm("username"))

こんな書き方が出来ます。最初の入力フィールドと同じ結果になるなら、なぜ別の書き方を覚えなきゃいけないのか、となりますが、上記の一文はデフォルトで以下のような少しリッチなHTMLに展開されます。

楽ですね。でも、このHTMLがそのまま欲しい記述とマッチしない場合も多いと思います。もちろん直接書いても良いのですが、helperの使い方を変えずに上記のテンプレートを切り替えるFieldConstructorという仕組みも提供されています。最初に紹介した予め提供されているBootstrap用のFieldConstrutorを使ってみましょう。先ほどのテンプレートのファイルに下記の一行を加えます。

@import helper.twitterBootstrap._

すると、同じhelperの記述のままで展開するHTMLが変わります。

あっさり変わりました。HTML内に項目がいくつあっても@importの一行で全て変わってくれます。他にも個々のlabelの名称やclassなどもhelperの使い方で変えることが出来ます。(詳細はこちら

Bootstrap2.0対応のテンプレートを作る

さっきのFieldConstructorはBootstrap2.0に対応しておらず、少し表示が崩れてしまいます。簡単に出来るので作ってしまいましょう。Play2.0で作成したプロジェクトのapp/viewsにbootstrapField.scala.htmlというファイルを以下の内容で作ります。なおファイル名は呼び出し時の名称(関数名)になります。

同じディレクトリにこれをimplicitな値として保持するobjectを作ります。

これで準備完了です。後は適用したいテンプレートで

@import views.BootstrapHelper._

と書きましょう。これで先ほどのhelperの出力はこのようになります。

classが変わりましたね。ちなみに先ほどのobjectは書かずに直接テンプレートにimplicitな値として記述する方法もあります。

@implicitField = @{ FieldConstructor(bootstrapField.f) }

どちらでも好きな方を使いましょう。
さて、実際に今回の対応を行っただけで、ほぼ同じテンプレートでも見栄えはここまで変わります。

使用前(FieldConstructor指定無し、BootstrapのCSS無し)

使用後

素晴らしい!たったこれだけで、目も当てられない見た目から、大幅に改善しましたね。Bootstrap最高です。

複数のFieldConstructor

さて、これまでページ内の全てのフィールドを同じ記述にする方法について見ていきましたが、個別にFieldConstructorを適用することも可能です。FieldConstructorはimplicitパラメータとして受け取るようになっているので、渡さなければスコープ内のimplicitな値が使われますが、明示的に引数として渡すことが可能です。先ほどのbootstrapField.scala.htmlにborderを足したものをborderedBootstrapField.scala.htmlというファイル名で新たに作ります。

control-groupのdivにstyle属性を足しています。そしてこれを変更したい項目の引数として渡しましょう。(play.api.i18n.Langも必要となりますが、ここでは詳細を割愛します)

@inputText(userForm("username"))(FieldConstructor(borderedBootstrapField.f), lang)

見た目はこうなりました。(アラートとかは抜いています)

簡単でしたね。
Play2.0は再利用可能なテンプレートを簡単に作れるので、他のBootstrapのパーツなどもhelperにしてしまってどんどん作りましょう。