§テンプレートエンジン
§Scala ベースのタイプセーフなテンプレートエンジン
Play 2.0 には強力な Scala ベースのテンプレートエンジンが新たに同梱されています。この新しいテンプレートエンジンのデザインは、ASP.NET Razor にインスパイアされており、特徴は次のとおりです。
- 簡潔さ、表現力、書きやすさを重視: このテンプレートエンジンを利用すると、1 ファイルあたりに必要な文字数やタイプ量が最小化され、サクサクとコーディングができます。よくあるテンプレートの文法とは異なり、サーバで実行されるコードブロックを HTML 中に明示する必要がありませんので、コーディングを妨げることがありません。パーサが優秀なので、コードブロックと HTML 部分を自動的に区別することができるのです。これにより、簡潔さ、表現力、書きやすさに優れた文法になっています。
- 学習コストが低い: テンプレート文法は最小限になっているので、すぐにテンプレートを書き始めることができます。簡潔な Scala の構文を使うことができ、また HTML についての知識がそのまま応用できます。
- 新しい言語ではありません: Play framework の開発者は、新しい言語を作ることを意識的に避けました。その代わり、Scala 版のフレームワークの利用者が、テンプレートのマークアップ言語を拡張できるようにしました。
- エディタを選ばない: 特別なツールがなくても、ただのテキストエディタで書くことができます。
ノート: テンプレートエンジンは Scala を式言語として使っていますが、これは Java 開発者にとって問題にはなりません。式言語は Java とほとんど同じ物として扱うことができます。
テンプレートは複雑なロジックを記述する場所ではない事を忘れないで下さい。複雑な Scala コードをここに書く必要はありません。ほとんどの場合は以下のようにモデルオブジェクトからデータにアクセスするだけで済むでしょう。
myUser.getProfile().getUsername()
引数の型は後置形式で指定されます。ジェネリックスの型は Java の
<>
構文の代わりに[]
で指定されます。例えば、 Java でのList<String>
と同じ意味でList[String]
と書きます。
テンプレートはコンパイルされて、エラーはブラウザ上で確認することができます。
§概観
Play Scala テンプレートは Scala のコードブロックを少し含む以外は、ただのテキストファイルです。したがって、HTML, XML, CSV などあらゆるテキストベースのフォーマットを生成するために利用できます。
テンプレートシステムは HTML に慣れた人に向けて設計されているので、フロントエンドエンジニアでも簡単に書くことができます。
テンプレートは簡単な命名規則に従って、ただの Scala の関数としてコンパイルされます。views/Application/index.scala.html
というテンプレートファイルを作成すると、コンパイルにより views.html.Application.index
という render()
メソッドを持つクラスが生成されます。
例えば、次のようなシンプルなテンプレートを作成します。
@(customer: Customer, orders: List[Order])
<h1>Welcome @customer.name!</h1>
<ul>
@for(order <- orders) {
<li>@order.getTitle()</li>
}
</ul>
このテンプレートは次のような static メソッド呼び出しにより、Java コード中のどこからでも呼び出すことができます。
Content html = views.html.Application.index.render(customer, orders);
§文法: 魔法の @
Scala テンプレートでは @
という文字が唯一の特殊文字です。この文字はテンプレート中に登場すると動的コードの開始として認識されます。コードブロックの終わりはコンパイラにより自動的に推論されるため、明示的に閉じる必要がありません。
Hello @customer.getName()!
^^^^^^^^^^^^^^^^^^
Dynamic code
テンプレートエンジンがコードを解析してコードブロックの終わりを自動的に認識するため、この文法では単純な Scala 文しかサポートされません。複数のトークンにまたがるようなコードを挿入したい場合は、その範囲を括弧で明示することができます。
Hello @(customer.getFirstName() + customer.getLastName())!
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Dynamic Code
同様に、複数の文を含むコードを挿入したい場合は、中括弧を利用することができます。
Hello @{val name = customer.getFirstName() + customer.getLastName(); name}!
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Dynamic Code
@
は特殊文字ですが、これをエスケープしたいときは @@
と書きます。
My email is bob@@example.com
§テンプレート引数
テンプレートは関数のように引数をとります。引数はテンプレートの先頭行で宣言します。
@(customer: models.Customer, orders: List[models.Order])
引数のデフォルト値を設定することもできます。
@(title: String = "Home")
複数の引数グループを作成することもできます。
@(title:String)(body: Html)
§反復
for
キーワードをよくある形で使うことができます。
<ul>
@for(p <- products) {
<li>@p.getName() ([email protected]())</li>
}
</ul>
ノート: 次の行に式が続いていることを示すために、
for
と同じ行に{
を置いていることを確認してください。
§If ブロック
If ブロックについても特別なことはなにもありません。Scala の if
式がそのまま使えます。
@if(items.isEmpty()) {
<h1>Nothing to display</h1>
} else {
<h1>@items.size() items!</h1>
}
§再利用可能なブロックの宣言
次のように、再利用可能なコードブロックを作成することができます。
@display(product: models.Product) = {
@product.getName() ([email protected]())
}
<ul>
@for(product <- products) {
@display(product)
}
</ul>
再利用可能な Scala のコードブロックを宣言することもできます。
@title(text: String) = @{
text.split(' ').map(_.capitalize).mkString(" ")
}
<h1>@title("hello world")</h1>
ノート: このようにコードブロックをテンプレートで宣言すると便利なこともありますが、テンプレートは込み入ったロジックを置く場所としては適切でないことを覚えておいてください。このようなコードは 通常の Java クラスに切り出すと良いことが多いです。 (必要であれば、
views/
パッケージ以下に通常の Java クラスを置くこともできます。)
慣習として、名前が implicit で始まる再利用可能なブロックは、implicit
として扱われます。
@implicitFieldConstructor = @{ MyFieldConstructor() }
§再利用可能な値の宣言
defining
ヘルパ関数を使って、特定のスコープ内でのみ有効な値を定義することができます。
@defining(user.getFirstName() + " " + user.getLastName()) { fullName =>
<div>Hello @fullName</div>
}
§import 文
テンプレート (またはサブテンプレート) の冒頭で、任意のパッケージやオブジェクトなどを import することができます。
@(customer: models.Customer, orders: List[models.Order])
@import utils._
...
絶対パスでパッケージを指定をしたい場合は、import 文で先頭に _root_ を指定します。
@import _root_.company.product.core._
全てのテンプレートで必要な共通の import 文がある場合は、 project/Build.scala
で指定することができます。
val main = PlayProject(…).settings(
templatesImport += "com.abc.backend._"
)
§コメント
@* *@
を利用して、サーバーサイドのブロックコメントを書くことができます。
@*********************
* 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: よくある使い方