§テンプレートエンジン
§Scalaベースの型安全なテンプレートエンジン
Playには、ASP.NET Razorに影響を受けた強力なScalaベースのテンプレートエンジンであるTwirlが付属しています。特に、それは
- 簡潔、表現力豊か、そして流動的: ファイル内で必要な文字数とキーストロークを最小限に抑え、高速で流動的なコーディングワークフローを可能にします。ほとんどのテンプレート構文とは異なり、HTML内でサーバーブロックを明示的に示すためにコーディングを中断する必要はありません。パーサーはあなたのコードからこれを推測するのに十分にスマートです。これにより、クリーンで高速かつ入力が楽しい、非常にコンパクトで表現力豊かな構文が可能になります。
- 学習が簡単: 最小限の概念で、すぐに生産性を高めることができます。既存のすべてのHTMLスキルと簡単なScala構文を使用します。
- 新しい言語ではない: 私たちは新しい言語を作成しないことを意識的に選択しました。代わりに、Scala開発者が既存のScala言語スキルを使用できるようにし、素晴らしいHTML構築ワークフローを可能にするテンプレートマークアップ構文を提供したいと考えました。
- あらゆるテキストエディタで編集可能: 特定のツールを必要とせず、あらゆるプレーンテキストエディタで生産性を高めることができます。
テンプレートはコンパイルされるため、ブラウザにエラーが表示されます。
§概要
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
またはコレクション(Seq
、Array
、TraversableOnce
)内にラップされている場合、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>
ブラウザでは次のように表示されます
このドキュメントにエラーを見つけましたか?このページのソースコードはこちらにあります。ドキュメントガイドラインを読んだ後、お気軽にプルリクエストで貢献してください。質問や共有するアドバイスがありますか?コミュニティフォーラムにアクセスして、コミュニティとの会話を開始してください。