§テンプレートエンジン
§Scala ベースのタイプセーフなテンプレートエンジン
Play 2.0 には強力な Scala ベースのテンプレートエンジンが新たに同梱されています。この新しいテンプレートエンジンのデザインは、ASP.NET Razor にインスパイアされており、特徴は次のとおりです。
- 簡潔さ、表現力、書きやすさを重視: このテンプレートエンジンを利用すると、1 ファイルあたりに必要な文字数やタイプ量が最小化され、サクサクとコーディングができます。よくあるテンプレートの文法とは異なり、サーバで実行されるコードブロックを HTML 中に明示する必要がありませんので、コーディングを妨げることがありません。パーサが優秀なので、コードブロックと HTML 部分を自動的に区別することができるのです。これにより、簡潔さ、表現力、書きやすさに優れた文法になっています。
- 学習コストが低い: テンプレート文法は最小限になっているので、すぐにテンプレートを書き始めることができます。Scala と HTML についての知識がそのまま応用できます。
- 新しい言語ではありません: Play framework の開発者は、新しい言語を作ることを意識的に避けました。その代わり、フレームワークの利用者がこれまでの Scala の知識をそのまま使って、テンプレートのマークアップ言語を拡張できるようにしました。
- エディタを選ばない: 特別なツールがなくても、ただのテキストエディタで書くことができます。
テンプレートはコンパイルされて、エラーはブラウザ上で即座に確認することができます。
§概観
Play Scala テンプレートは Scala のコードブロックを少し含む以外は、ただのテキストファイルです。したがって、HTML, XML, CSV などあらゆるテキストベースのフォーマットを生成するために利用できます。
テンプレートシステムは HTML に慣れた人に向けて設計されているので、web デザイナでも簡単に書くことができます。
テンプレートは簡単な命名規則に従って、ただの Scala の関数としてコンパイルされます。views/Application/index.scala.html
というテンプレートファイルを作成すると、コンパイルにより views.html.Application.index
という関数が生成されます。
例えば、次のようなシンプルなテンプレートを作成します。
@(customer: Customer, orders: Seq[Order])
<h1>Welcome @customer.name!</h1>
<ul>
@orders.map { order =>
<li>@order.title</li>
}
</ul>
このテンプレートは次のような関数呼び出しにより、Scala コード中のどこからでも呼び出すことができます。
val html = views.html.Application.index(customer, orders)
§文法: 魔法の @
Scala テンプレートでは @
という文字が唯一の特殊文字です。この文字はテンプレート中に登場すると Scala コードの開始として認識されます。コードブロックの終わりはコンパイラにより自動的に推論されるため、明示的に閉じる必要がありません。
Hello @customer.name!
^^^^^^^^^^^^^
Scala code
テンプレートエンジンがコードを解析してコードブロックの終わりを自動的に認識するため、この文法では単純な Scala 文しかサポートされません。複数のトークンにまたがるようなコードを挿入したい場合は、その範囲を括弧で明示することができます。
Hello @(customer.firstName + customer.lastName)!
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Scala Code
同様に、複数の文を含むコードを挿入したい場合は、通常の Scala コードと同様、中括弧を利用することができます。
Hello @{val name = customer.firstName + customer.lastName; name}!
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Scala Code
@
は特殊文字ですが、これをエスケープしたいときは @@
と書きます。
My email is bob@@example.com
§テンプレート引数
テンプレートはただの関数なので、引数をとります。引数はテンプレートの先頭行で宣言します。
@(customer: models.Customer, orders: Seq[models.Order])
引数のデフォルト値を設定することもできます。
@(title: String = "Home")
複数の引数グループを作成することもできます。
@(title:String)(body: Html)
さらに、implicit parameter を利用することもできます。
@(title: String)(body: Html)(implicit request: RequestHeader)
§反復
通常の Scala コード内とほぼ同じように、for 式を利用することができます。通常の for 式との違いとして、テンプレートコンパイラが yield
キーワードをブロックの直前に挿入することに注意してください。
<ul>
@for(p <- products) {
<li>@p.name ([email protected])</li>
}
</ul>
ご存知かもしれませんが、for 式は map のシンタックスシュガーですので、先程の例は次のように map を使って書くのと同じ意味になります。
<ul>
@products.map { p =>
<li>@p.name ([email protected])</li>
}
</ul>
§If ブロック
If ブロックについても特別なことはなにもありません。Scala の if
式がそのまま使えます。
@if(items.isEmpty) {
<h1>Nothing to display</h1>
} else {
<h1>@items.size items!</h1>
}
§パターンマッチング
テンプレートにおいてパターンマッチングを利用することもできます。
@connected match {
case models.Admin(name) => {
<span class="admin">Connected as admin (@name)</span>
}
case models.User(name) => {
<span>Connected as @name</span>
}
}
§再利用可能なブロックの宣言
次のように、再利用可能なコードブロックを作成することができます。
@display(product: models.Product) = {
@product.name ([email protected])
}
<ul>
@products.map { p =>
@display(product = p)
}
</ul>
再利用可能な Scala のコードブロックを宣言することもできます。
@title(text: String) = @{
text.split(' ').map(_.capitalize).mkString(" ")
}
<h1>@title("hello world")</h1>
ノート: このように Scala ブロックをテンプレートで宣言すると便利なこともありますが、テンプレートは込み入ったロジックを置く場所としては適切でないことを覚えておいてください。このようなコードは 通常の Scala ソースファイルに切り出すと良いことが多いです。 (必要であれば、
views/
パッケージ以下に通常の Scala ソースファイルを置くこともできます。)
慣習として、名前が implicit で始まる再利用可能なブロックは、implicit
として扱われます。
@implicitFieldConstructor = @{ MyFieldConstructor() }
§再利用可能な値の宣言
defining
ヘルパ関数を使って、特定のスコープ内でのみ有効な値を定義することができます。
@defining(user.firstName + " " + user.lastName) { fullName =>
<div>Hello @fullName</div>
}
§import 文
テンプレート (またはサブテンプレート) の冒頭で、任意のパッケージやオブジェクトなどを import することができます。
@(customer: models.Customer, orders: Seq[models.Order])
@import utils._
...
§コメント
@* *@
を利用して、サーバーサイドのブロックコメントを書くことができます。
@*********************
* This is a comment *
*********************@
テンプレートの先頭行にコメントを記述すると、Scala API doc にドキュメントが出力されます。
@*************************************
* Home page. *
* *
* @param msg The message to display *
*************************************@
@(msg: String)
<h1>@msg</h1>
§エスケープ
デフォルトでは、動的なコンテンツ部分はテンプレートの型 (HTML や XML など) に応じてエスケープされます。エスケープなしでコンテンツを出力したい場合、コンテンツをテンプレートのコンテンツタイプでラップしてください。
例えば、生の HTML を出力する場合は次のように記述します。
<p>
@Html(article.content)
</p>
Next: よくある使い方
このドキュメントの翻訳は Play チームによってメンテナンスされているものではありません。 間違いを見つけた場合、このページのソースコードを ここ で確認することができます。 ドキュメントガイドライン を読んで、お気軽にプルリクエストを送ってください。