文件

§範本引擎

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

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

注意:儘管範本引擎使用 Scala 作為表達式語言,但這對於 Java 開發人員來說並不是問題。您幾乎可以使用它,就好像該語言是 Java 一樣。

請記住,範本不是編寫複雜邏輯的地方。您不必在此處編寫複雜的 Scala 程式碼。大多數情況下,您只需從模型物件中存取資料,如下所示

myUser.getProfile().getUsername()

使用後綴語法指定參數類型。使用 [] 符號指定泛型類型,而不是通常的 <> Java 語法。例如,您編寫 List[String],這與 Java 中的 List<String> 相同。

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

§概述

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

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

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

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

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

下一步:使用範本進行依賴注入


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