1. 序章

このチュートリアルでは、 PlayFrameworkでScalaを使用してテンプレートを使用する方法を学習します。 テンプレートファイルを定義し、コントローラーからパラメーターを渡し、テンプレートで依存性注入を使用する方法を学習します。

2. テンプレートの定義

Play Frameworkテンプレートは、テンプレート変数をパラメーターとして受け取り、HTMLコードを返す関数のように機能します BaeldungPlayFrameworkチュートリアルのいくつかへのリンクを含むページを作成するとします。

まず、index.scala.htmlファイルをviews.Baeldungパッケージに作成します。

@(articles: List[(String, String)])
<h1>Baeldung Play tutorials</h1>

<ul>
    @for(article <- articles) {
    <li><a href="@article._2">@article._1</a></li>
    }
</ul>

テンプレートファイルの最初の行にはパラメータが含まれています。このテンプレートでは、入力としてタプルのリストが必要です。

ファイルの残りの部分は、テンプレート操作を含むHTMLコードです。 テンプレートエンジンは、@文字で始まるすべてのものを提供します。 この例では、 @for 演算子を使用して記事のリストを反復処理し、 @ article._1 変数を使用して記事のタイトルにアクセスし、@article._2を使用します。 記事のURLにアクセスします。

3. コントローラでテンプレートを使用する

それでは、テンプレートを使用して応答を生成するコントローラーを定義しましょう

class ViewTemplateController @Inject()(cc: ControllerComponents)
        extends AbstractController(cc) {

  def index = Action { implicit request =>
    val articles = List(
      ("Introduction to Play Framework", "https://www.baeldung.com/scala/play-framework-intro"),
      ("Building REST API in Scala with Play Framework", "https://www.baeldung.com/scala/play-rest-api")
    )
    Ok(views.html.Baeldung.index(articles))
  }
}

テンプレートファイルを定義すると、Play Frameworkによってクラスが自動的に作成され、HTML出力を返す関数として使用できることがわかります。

4. テンプレートでのカスタムクラスの使用

この記事では、テンプレートに2つのパラメーターを含む簡単な例を示します。 したがって、タプルを間違えずに使用するのは簡単です。 しかし、15個のパラメーターが必要な場合はどうなるでしょうか。 幸い、テンプレートを定義するときに、組み込みの型だけを使用する必要はありません。

クラスを定義すると、テンプレートとコントローラーの両方で使用できます

case class Article(title: String, url: String)

def withClass = Action { implicit request =>
  val articles = List(
    Article("Introduction to Play Framework", "https://www.baeldung.com/scala/play-framework-intro"),
    Article("Building REST API in Scala with Play Framework", "https://www.baeldung.com/scala/play-rest-api")
  )
  Ok(views.html.Baeldung.with_class(articles))
}

これで、テンプレートはArticleのリストをパラメーターとして受け入れることができます。

@(articles: List[Article])
<h1>Baeldung Play tutorials</h1>

<ul>
  @for(article <- articles) {
  <li><a href="@article.url">@article.title</a></li>
  }
</ul>

5. テンプレートへの依存性注入

パラメータに加えて、テンプレートにオブジェクトを挿入することもできます。 これは、テンプレート内でヘルパー関数を使用する場合に役立ちます。 次の例では、短いメニューでページを定義し、依存性注入を使用して価格フォーマットをテンプレートに渡します。 コントローラから始めましょう:

case class Product(productName: String, price: Double, isAvailable: Boolean)

class MenuController @Inject()(template: views.html.Baeldung.menu, cc: ControllerComponents)
        extends AbstractController(cc) {

  def availableProducts = Action { implicit request =>
    val products = List(
      Product("coffee", 8.99, true),
      Product("cake", 12.00, true),
      Product("pancake", 3.00, false)
    )
    Ok(template(products))
  }
}

上記のコードでは、テンプレートのインスタンスをコントローラーオブジェクトに挿入していることに注意してください。 これは、テンプレートに依存関係も挿入しているために必要です

@this(priceFormatter: PriceFormatter)
@(products: List[Product])
<ul>
  @for(product <- products) {
    <li>@product.productName @priceFormatter(product.price)</li>
  }
</ul>

テンプレートの最初の行は、テンプレートコンストラクターです。 テンプレートにコンストラクターを定義し、依存性注入を使用してテンプレートをコントローラーに渡すと、PlayFrameworkは依存性を自動的に注入します。

6. 条件付きロジック

前の例には、製品が利用可能かどうかを示すboolean変数があります。 メニューで利用できない商品の外観を変更したい場合はどうなりますか?

Play Frameworkテンプレートでは、条件演算子を使用して、使用できない製品を別の方法でレンダリングできます。

@if(product.isAvailable) {
  <li>@product.productName @priceFormatter(product.price)</li>
} else {
  <li><strike>@product.productName @priceFormatter(product.price)</strike></li>
}

7. テンプレートでの関数の定義

テンプレートに多くのループと条件ステートメントを追加すると、そのコードはすぐに判読できなくなり、保守が困難になります。テンプレートファイルで関数を定義することで、この問題を解決できます。

このような関数はパラメーターを受け入れ、テンプレートの一部を返します。 したがって、このアプローチを使用して、前の2つの例を書き直すことができます。

@display(product: Product) = {
  @if(product.isAvailable) {
    <li>@product.productName @priceFormatter(product.price)</li>
  } else {
    <li><strike>@product.productName @priceFormatter(product.price)</strike></li>
  }
}

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

@display キーワードは、単一のProductパラメーターを持つ「display」と呼ばれる関数を定義します。 関数の本体は、返されるテンプレートです。 テンプレート関数でも、以前に挿入されたヘルパー関数を使用できることに注意してください。

8. 結論

この記事では、Play Frameworkでテンプレートを定義し、それらをコントローラーで使用し、依存関係をテンプレートに渡す方法を示しました。

PriceFormatter と残りのコードの実装は、GitHub利用できます。