文件

§範本引擎

§基於 Scala 的類型安全範本引擎

Play 附帶 Twirl,這是一個強大的基於 Scala 的範本引擎,其設計靈感來自 ASP.NET Razor。具體來說,它

 

範本經過編譯,因此您會在瀏覽器中看到任何錯誤

§概述

Play Scala 範本是一個簡單的文字檔案,包含小區塊的 Scala 程式碼。範本可以產生任何基於文字的格式,例如 HTML、XML 或 CSV。

範本系統的設計讓習慣使用 HTML 的人感到舒適,讓前端開發人員能輕鬆使用範本。

範本編譯為標準 Scala 函數,遵循簡單的命名慣例。如果您建立一個 views/Application/index.scala.html 範本檔案,它將產生一個 views.html.Application.index 類別,其中有一個 apply() 方法。

例如,以下是一個簡單的範本

@(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>

會在瀏覽器中呈現為

下一頁:範本的相依性注入


在此文件發現錯誤?此頁面的原始程式碼可在此處找到 這裡。閱讀 文件指南 後,請隨時提交拉取請求。有問題或建議要分享?前往 我們的社群論壇 與社群展開對話。