Play framework 2.0 RCが出たようです13 – Bootstrapを使う
RC版のリリース
2月某日、以前からの予告どおり、Playframework2.0のRC版がリリースされました。 現在はRC2がダウンロード可能で、近々RC3がリリースされるものと思われます。 RCとはいえ、まだバグフィックスや機能追加が頻繁にされておりますので使用にはご注意を。
Bootstrapとは?
Bootstrapとは、twitterが提供するWebアプリケーション用CSSフレームワークです。 いくつかのファイルを読み込んで決まったスタイルを指定するだけで、見栄えの良い画面を作成することができます。 boootstrapのデモをみてみましょう。
こんな何の変哲もない画面が、
BootstrapのCSSを追加して、タグにあらかじめ定義されたクラスを適用するだけで、このような画面になります。
非常に簡単です。手軽にある程度見栄えの良い画面を作成するには十分すぎる機能をもっていますし、カスタマイズも可能です。 今回はPlayframeworkのScalaテンプレートからBootstrapをつかってみます。
PlayframeworkからBootstrapを使用するには
Playframework2.0ではデフォルトでScalaテンプレートを使用してビューを記述します。 これはいわゆるJSPみたいなもので、htmlの中にScalaのコードを埋め込むようなことができます。 普通にHTMLを記述するなら、特別なことはせずBootstrapを使用できるのですが、 helper.twitterBootstrapパッケージを使用すれば、フォームを使用するときに自動的にスタイルを適用してくれます。 ではフォームをつくってみましょう。
今回使用した動作環境は以下のとおりです。
- OS : MacOS X 10.7.2
- Playframework : HEAD
- Java : 1.6.0_26
- Bootstrap : 2.0
注意: この記事ではgithubから取得したHEAD版を使用して試しています。 正式リリース前の状況のため思わぬ不具合が生じるかもしれませんので、ご了承ください。
ソースのHEADを取得してセットアップ
まだgithubからソースを取得していない人は、play2.0のソースを取得してビルドしましょう。
$ git clone https://github.com/playframework/Play20.git $ cd Play20/framework $ ./build > complile > build-repository > publish-local
すでにソースを取得している人は、最新の状態に更新してビルドします。
$ git pull $ cd Play20/framework $ ./cleanEverything $ ./build > compile > build-repository > publish-local
これで準備ができました。
プロジェクト作成
Scalaベースのプロジェクトを作成し、sbtコンソールを起動します。
% play new bootstrap % cd bootstrap % play
eclipsifyを実行してeclipseプロジェクト化してインポートしてソースの修正をしましょう。
>[bootstrap] $ eclipsify
Bootstrapをダウンロード&コピー
まずはここからBootstrapをダウンロードして解凍します。 bootstrapプロジェクトディレクトリのpublic下にbootstrapディレクトリを作成し、そこにboostrap/css,bootstrap/img,bootstrap/jsをコピーします。
Controller修正
Applicationコントローラーを修正します。 フォーム表示関数(form)とフォームサブミット関数(submit)を作成します。 Formに関する部分は、このあたりをごらんください。
package controllers import play.api._ import play.api.mvc._ import play.api.data._ import play.api.data.Forms._ import views._ object Application extends Controller { val userForm: Form[User] = Form( // Userフォームマッピング mapping( "username" -> text(minLength = 4), "email" -> email, "password" -> tuple( "main" -> text(minLength = 6), "confirm" -> text ).verifying( // パスワードの入力ルール定義 "Passwords don't match", passwords => passwords._1 == passwords._2 )) { // Userフォームバインド (username, email, passwords) => User(username, passwords._1, email) } { // Usetフォームアンバインド user => Some(user.username, user.email, (user.password, "")) }.verifying( "This username is not available", user => !Seq("admin", "guest").contains(user.username) )) /** * ユーザー登録. */ def form = Action { Ok(views.html.index(userForm)); } /** * ユーザー登録結果. */ def submit = Action { implicit request => userForm.bindFromRequest.fold( errors => BadRequest(views.html.index(errors)), user => Ok(views.html.result(user)) ) } } //ユーザー情報クラスを定義 case class User( username: String, password: String, email: String )
Scalaテンプレート修正
まずはapp/views/main.scala.htmlを修正します。 Bootstrapを読みこむようにしましょう。
@(title: Html, nav: String = "")(content: Html) <!DOCTYPE html> <html> <head> <title>@title</title> <link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")"> <link rel="stylesheet" media="screen" href="@routes.Assets.at("bootstrap/css/bootstrap.min.css")" > <link rel="shortcut icon" type="image/png" href="@routes.Assets.at("images/favicon.png")"> <script src="@routes.Assets.at("javascripts/jquery-1.7.1.min.js")" type="text/javascript"></script> <script src="@routes.Assets.at("bootstrap/js/bootstrap.min.js")" type="text/javascript"></script> </head> <body> @content </body> </html>
次はindex.scala.htmlにフォームを記述します。 バインド済みのuserForm変数を用いて、@helper.formでフォームタグ生成、エラーメッセージやラベルを指定しています。 スタイルに関する記述はおこなっていません。
@(userForm: Form[User]) @import helper._ @import helper.twitterBootstrap._ @title = { ユーザー登録 } @main(title, nav = "signup") { <div class="container"> <div class="hero-unit"> <h1>Bootstrap with Play2.0!</h1> <p>このサンプルはBootstrapをPlay2.0から使用しています。</br>これはPlay2.0のFormサンプルを元に作成されています。</p> <p><a href="https://github.com/playframework/Play20/wiki/ScalaFormHelpers" class="btn btn-primary btn-large">Learn more »</a></p> </div> @helper.form(action = routes.Application.submit) { <fieldset> <legend>ユーザー登録サンプル</legend> @inputText( userForm("username"), '_label -> "名前", '_help -> "有効なユーザー名を入力してください.", '_error -> userForm.globalError ) @inputText( userForm("email"), '_label -> "email", '_help -> "有効なメールアドレスを入力してください." ) @inputPassword( userForm("password.main"), '_label -> "パスワード", '_help -> "パスワードは6文字以上にしてください. " ) @inputPassword( userForm("password.confirm"), '_label -> "パスワード確認", '_help -> "もう一度パスワードを入力してください.", '_error -> userForm.error("password") ) </fieldset> <div class="actions"> <input type="submit" class="btn primary" value="登録"> <a href="@routes.Application.submit" class="btn">キャンセル</a> </div> } </div> }
そしてサブミット結果であるresult.scala.htmlを記述します。
@(user: User) @title = { ユーザー登録結果 } @main(title, nav = "signup") { <div class="container"> <div class="hero-unit"> <h1>Bootstrap with Play2.0!</h1> <p>このサンプルはBootstrapをPlay2.0から使用しています。</br>これはPlay2.0のFormサンプルを元に作成されています。</p> <p><a href="https://github.com/playframework/Play20/wiki/ScalaFormHelpers" class="btn btn-primary btn-large">Learn more »</a></p> </div> <h1>入力された情報</h1> </br> <h3>ユーザー名</h3> <p> @user.username </p> <h3>メールアドレス</h3> <p> @user.email </p> <h3>パスワード</h3> <p> @user.password </p> </div> }
routes修正
最後にroutesを修正します。
# Home page #GET / controllers.Application.index # Map static resources from the /public folder to the /assets URL path GET /assets/*file controllers.Assets.at(path="/public", file) GET /signup controllers.Application.form POST /signup controllers.SignUp.submit
動作確認
アプリケーションを起動してブラウザでアクセスしてみてください。 Bootstrapが適用されていることがわかります。
>[bootstrap] $ compile >[bootstrap] $ run