§テンプレートエンジン
§Scalaベースの型安全なテンプレートエンジン
Playには、ASP.NET Razorにインスパイアされた強力なScalaベースのテンプレートエンジンであるTwirlが付属しています。具体的には、次のとおりです。
- コンパクトで表現力豊かで流動的: ファイルに必要な文字数とキーストローク数を最小限に抑え、高速で流動的なコーディングワークフローを可能にします。ほとんどのテンプレート構文とは異なり、HTML内にサーバーブロックを明示的に示すためにコーディングを中断する必要はありません。パーサーはコードからこれを推測するほどスマートです。これにより、クリーンで高速で、入力するのが楽しい、非常にコンパクトで表現力豊かな構文が可能になります。
- 習得が簡単: 最小限の概念で、すぐに生産性を向上させることができます。シンプルなScala構造と、既存のすべてのHTMLスキルを使用します。
- 新しい言語ではない: 新しい言語を作成しないことを意識的に選択しました。代わりに、Scala開発者が既存のScala言語スキルを使用できるようにし、素晴らしいHTML構築ワークフローを可能にするテンプレートマークアップ構文を提供したいと考えました。
- 任意のテキストエディターで編集可能: 特定のツールは必要なく、通常のプレーンテキストエディターで生産性を向上させることができます。
注: テンプレートエンジンは式言語として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
テンプレートファイルを作成すると、render()
メソッドを持つviews.html.Application.index
クラスが生成されます。
たとえば、以下はシンプルなテンプレートです。
@(customer: Customer, orders: List[Order])
<h1>Welcome @customer.name!</h1>
<ul>
@for(order <- orders) {
<li>@order.getTitle()</li>
}
</ul>
その後、通常のクラスでメソッドを呼び出すのと同じように、任意のJavaコードからこれを呼び出すことができます。
Content html = views.html.Application.index.render(customer, orders);
§構文: 魔法の「@」文字
Scalaテンプレートでは、@
を単一の特殊文字として使用します。この文字が出現するたびに、動的ステートメントの開始を示します。コードブロックを明示的に閉じる必要はありません。動的ステートメントの終わりはコードから推測されます。
Hello @customer.getName()!
^^^^^^^^^^^^^^^^^^
Dynamic code
テンプレートエンジンはコードを分析することでコードブロックの終わりを自動的に検出するため、この構文は単純なステートメントのみをサポートします。複数のトークンを含むステートメントを挿入する場合は、括弧を使用して明示的にマークします。
Hello @(customer.getFirstName() + customer.getLastName())!
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Dynamic Code
注: 動的ステートメントのキーワードと括弧の間に空白を含めないようにしてください。
たとえば、次のコードは機能しません。
@for (menu <- menuList) { ... } // Compilation error: '(' expected but ')' found. ^
中括弧を使用して、複数ステートメントブロックを記述することもできます。
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)
§テンプレートコンストラクター
デフォルトでは、テンプレートは任意のコンテキストで呼び出すことができる静的関数として生成されます。テンプレートがメッセージAPIなどのコンポーネントに依存している場合、必要なコンポーネント(および他のテンプレート)を使用してテンプレートを注入する方が簡単な場合があります。その後、そのテンプレートをそれを使用するコントローラーに注入できます。
Twirlは、テンプレートのコンストラクターを宣言することをサポートしています。テンプレートパラメータの前のファイルの先頭に@this()
構文を使用します。コンストラクターの引数は、テンプレートパラメータと同じ方法で定義できます。
@this(messagesApi: MessagesApi)
@(customer: models.Customer, orders: List[models.Order])
§反復処理
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>
再利用可能な純粋なコードブロックを宣言することもできます。
@title(text: String) = @{
text.split(' ').map(_.capitalize).mkString(" ")
}
<h1>@title("hello world")</h1>
注: テンプレートでこのようにコードブロックを宣言することは便利な場合がありますが、テンプレートは複雑なロジックを記述するのに最適な場所ではないことに留意してください。これらの種類のコードをJavaクラス(必要に応じて
views/
パッケージにも保存できます)で外部化する方が多くの場合優れています。
慣例により、implicitで始まる名前で定義された再利用可能なブロックはimplicit
としてマークされます。
@implicitFieldConstructor = @{ MyFieldConstructor() }
§再利用可能な値の宣言
defining
ヘルパーを使用して、スコープされた値を定義できます。
@defining(user.getFirstName() + " " + user.getLastName()) { fullName =>
<div>Hello @fullName</div>
}
§インポートステートメント
テンプレート(またはサブテンプレート)の先頭で、必要なものをインポートできます。
@(customer: models.Customer, orders: List[models.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>
次へ: テンプレートを使用した依存性注入
このドキュメントにエラーを見つけましたか?このページのソースコードはこちらにあります。ドキュメントのガイドラインを読んだ後、プルリクエストを自由に貢献してください。質問や共有するアドバイスはありますか?コミュニティフォーラムに参加して、コミュニティとの会話を始めてください。