Documentation

You are viewing the documentation for the 2.0.8 release in the 2.0.x series of releases. The latest stable release series is 2.4.x.

§テンプレートエンジン

§Scala ベースのタイプセーフなテンプレートエンジン

Play 2.0 には強力な Scala ベースのテンプレートエンジンが新たに同梱されています。この新しいテンプレートエンジンのデザインは、ASP.NET Razor にインスパイアされており、特徴は次のとおりです。

テンプレートはコンパイルされて、エラーはブラウザ上で即座に確認することができます。

§概観

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: よくある使い方