ドキュメント

§テンプレートエンジン

§Scalaベースの型安全なテンプレートエンジン

Playには、ASP.NET Razorに影響を受けた強力なScalaベースのテンプレートエンジンであるTwirlが付属しています。特に、それは

 

テンプレートはコンパイルされるため、ブラウザにエラーが表示されます。

§概要

Play Scala テンプレートは、Scalaコードの小さなブロックを含む単純なテキストファイルです。テンプレートは、HTML、XML、CSVなどのテキストベースのフォーマットを生成できます。

テンプレートシステムは、HTMLでの作業に慣れている人が快適に感じられるように設計されており、フロントエンド開発者がテンプレートを簡単に操作できるようにしています。

テンプレートは、単純な命名規則に従って、標準のScala関数としてコンパイルされます。views/Application/index.scala.htmlテンプレートファイルを作成すると、apply()メソッドを持つviews.html.Application.indexクラスが生成されます。

たとえば、これは簡単なテンプレートです。

@(customer: Customer, orders: List[Order])

<h1>Welcome @customer.name!</h1>

<ul>
@for(order <- orders) {
  <li>@order.title</li>
}
</ul>

これは、通常クラスのメソッドを呼び出すのと同じように、任意のScalaコードから呼び出すことができます。

val content = views.html.Application.index(c, o)

§構文:魔法の「@」文字

Scalaテンプレートは、単一の特殊文字として@を使用します。この文字が現れるたびに、動的ステートメントの開始を示します。コードブロックを明示的に閉じる必要はありません。動的ステートメントの終わりは、コードから推測されます。

Hello @customer.name!
       ^^^^^^^^^^^^^
       Dynamic code

テンプレートエンジンはコードを分析してコードブロックの終わりを自動的に検出するため、この構文は単純なステートメントのみをサポートします。マルチトークンステートメントを挿入する場合は、括弧を使用して明示的にマークしてください。

Hello @(customer.firstName + customer.lastName)!
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                    Dynamic Code

注: 動的ステートメントのキーワードと括弧の間に空白を含めないようにしてください。

たとえば、次のコードは機能しません。

@for (menu <- menuList) { ... }  // Compilation error: '(' expected but ')' found.
    ^

中括弧を使用して、複数ステートメントブロックを記述することもできます。

Hello @{val name = customer.firstName + customer.lastName; name}!
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                             Dynamic Code

@は特殊文字であるため、エスケープする必要がある場合があります。これを行うには、@@を使用します。

My email is bob@@example.com

§テンプレートパラメータ

テンプレートは関数のようなものなので、テンプレートファイルの先頭で宣言する必要があるパラメータが必要です。

@(customer: Customer, orders: List[Order])

パラメータにデフォルト値を使用することもできます。

@(title: String = "Home")

または、複数のパラメータグループを使用することもできます。

@(title: String)(body: Html)

§テンプレートコンストラクタ

デフォルトでは、テンプレートは任意のコンテキストで呼び出すことができる静的関数として生成されます。テンプレートがメッセージAPIなどのコンポーネントに依存している場合は、必要なコンポーネント(およびその他のテンプレート)で注入すると、それを使用するコントローラーにテンプレートを注入することが簡単になる場合があります。

Twirlは、テンプレートパラメータの前に、ファイルの先頭で@this()構文を使用して、テンプレートのコンストラクタを宣言することをサポートしています。コンストラクタへの引数は、テンプレートパラメータと同じ方法で定義できます。

@this(myComponent: MyComponent)

@(customer: Customer, orders: List[Order])

§反復

forキーワードをかなり標準的な方法で使用できます。

<ul>
@for(p <- products) {
  <li>@p.name ([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: Product) = {
  @product.name ([email protected])
}

<ul>
@for(product <- products) {
  @display(product)
}
</ul>

再利用可能な純粋なコードブロックを宣言することもできます。

@title(text: String) = @{
  text.split(' ').map(_.capitalize).mkString(" ")
}

<h1>@title("hello world")</h1>

注: テンプレートでこのようにコードブロックを宣言すると便利な場合がありますが、テンプレートは複雑なロジックを記述するのに最適な場所ではないことに注意してください。多くの場合、この種のコードをScalaクラスに外部化する方が適切です(必要に応じてviews/パッケージの下に保存することもできます)。

慣例により、implicitで始まる名前で定義された再利用可能なブロックは、implicitとしてマークされます。

@implicitFieldConstructor = @{ MyFieldConstructor() }

§再利用可能な値の宣言

definingヘルパーを使用して、スコープ付きの値を定義できます。

@defining(user.firstName + " " + user.lastName) { fullName =>
  <div>Hello @fullName</div>
}

§インポートステートメント

テンプレート(またはサブテンプレート)の先頭で、必要なものをインポートできます。

@(customer: Customer, orders: List[Order])

@import utils._

...

絶対解決を行うには、インポートステートメントでrootプレフィックスを使用します。

@import _root_.company.product.core._

すべてのテンプレートで必要な共通のインポートがある場合は、build.sbtで宣言できます。

TwirlKeys.templateImports += "org.abc.backend._"

§コメント

テンプレートでは、@* *@を使用してサーバー側のブロックコメントを記述できます。

@*********************
* This is a comment *
*********************@

最初の行にコメントを付けて、テンプレートをScala APIドキュメントに記述できます。

@*************************************
 * Home page.                        *
 *                                   *
 * @param msg The message to display *
 *************************************@
@(msg: String)

<h1>@msg</h1>

§エスケープ

デフォルトでは、動的コンテンツ部分は、テンプレートタイプ(例:HTMLまたはXML)のルールに従ってエスケープされます。生のコンテンツフラグメントを出力する場合は、テンプレートコンテンツタイプでラップします。

注: この機能を使用する場合は、ユーザーがコンテンツを制御できる可能性がある場合は、生のHTMLを出力することによるセキュリティへの影響を考慮してください。この手法は、クロスサイトスクリプティング(XSS)の脆弱性の一般的な原因であり、注意して使用しないと危険です。

たとえば、生のHTMLを出力するには

<p>
  @Html(article.content)
</p>

§文字列補間

テンプレートエンジンは、文字列補間として使用できます。基本的には、「@」を「$」に置き換えます。

import play.twirl.api.StringInterpolation

val name = "Martin"
val p    = html"<p>Hello $name</p>"

§Scala型の表示

通常、TwirlはScala型の値をそれらのtoStringメソッドを呼び出すことによってレンダリングします。ただし、値がOptionまたはコレクション(SeqArrayTraversableOnce)内にラップされている場合、Twirlは最初に値をアンラップしてからtoStringを呼び出します。

たとえば、

<ul>
  <li>@Option("value inside option")</li>
  <li>@List("first", "last")</li>
  <li>@User("Foo", "Bar")</li>
  <li>@List("hello", User("Foo", "Bar"), Option("value inside option"), List("first", "last"))</li>
</ul>

ブラウザでは次のように表示されます

次: テンプレートを使用した依存性注入


このドキュメントにエラーを見つけましたか?このページのソースコードはこちらにあります。ドキュメントガイドラインを読んだ後、お気軽にプルリクエストで貢献してください。質問や共有するアドバイスがありますか?コミュニティフォーラムにアクセスして、コミュニティとの会話を開始してください。