Play提供了基於Scala的強大模板引擎Twirl。它的誕生靈感來自於 ASP.NET Razor。它有以下特色:html
注意:雖然模板引擎使用了Scala做爲描述語言,這對Java開發者來講也不是問題。你能夠像使用Java那樣來用它。記住不要在模板中寫複雜的業務邏輯。這裏不須要複雜的Scala代碼,大多數狀況下你只須要接受數據而已,如: myUser.getProfile().getUsername()。前端
參數類型經過前綴來限定。泛型使用[],而不是Java的<>。如List[String]至關於Java裏面的List<String>。java
模板須要通過編譯,因此你能夠直接在瀏覽器上看到錯誤信息:api
Play Scala 模板就是一個簡單的包含着Scala代碼的文本。模板能夠生成任意的文本格式,如 HTML、XML或者CSV。數組
模板被設計爲HTML友好的,所以前端開發人員能夠直接在模板上工做。瀏覽器
模板被當成標準的Scala函數來編譯,只是加入了一些簡單的命名約定。若是建立了一個 view/Application/index.scala.html,將編譯生成一個包含着render()方法,名爲views.html.Application.index 的class文件:安全
@(customer: Customer, orders: List[Order]) <h1>Welcome @customer.name!</h1> <ul> @for(order <- orders) { <li>@order.title</li> } </ul>
你能夠在任意Java code中調用他,就像調用其餘class中的普通方法同樣:編輯器
Content html = views.html.Application.index.render(customer, orders);
Scala模板將'@'視做特殊符號。每當出現 @ 暗示着後邊跟着動態表達式。你不須要顯式地關閉代碼塊——編譯器會自動推斷它:函數
Hello @customer.getName()!
模板引擎將自動檢測代碼結束,所以這種語法只支持簡單的表達式。若是你須要插入複雜的表達式,你須要顯式的將它們放入括號中:工具
Hello @(customer.getFirstName() + customer.getLastName())!
注意:須要確保在關鍵字和動態表達式及括號之間不能加入空格,以下面的表達式將不起做用:
@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),可能注入是更好的選擇,包括將組件注入模板,及將模板注入controller。
Twirl 支持爲模板聲明構造函數。你能夠在模板最開始、其它參數以前使用 @this() 語法。構造函數的參數的定義形式和模板參數同樣:
@this(myComponent: MyComponent) @(customer: Customer, orders: List[Order])
使用 for 關鍵字來迭代,下面是標準用法:
<ul> @for(p <- products) { <li>@p.name ($@p.price)</li> } </ul>
注意:確保 { 和 for 在同一行,這樣能夠告知編譯器表達式將從下一行開始。
if表達式沒有任何特殊之處,就是Scala的if語句:
@if(items.isEmpty) { <h1>Nothing to display</h1> } else { <h1>@items.size items!</h1> }
能夠像下面這樣聲明可重用代碼塊:
@display(product: Product) = { @product.name ($@product.price) } <ul> @for(product <- products) { @display(product) } </ul>
也能夠聲明可重用的純Scala代碼:
@title(text: String) = @{ text.split(' ').map(_.capitalize).mkString(" ") } <h1>@title("hello world")</h1>
注意:聲明代碼塊有時是一種簡單的實現方式,可是請記住模板並非實現業務邏輯的地方。最好把它抽出來放到外部代碼中。
咱們約定以 implicit 命名開頭的方法,將被視做隱式方法:
@implicitFieldConstructor = @{ MyFieldConstructor() }
你可使用defining幫助類來定義域變量:
@defining(user.firstName + " " + user.lastName) { fullName => <div>Hello @fullName</div> }
你能夠在template開始出導入任意你想要的東西:
@(customer: Customer, orders: List[Order]) @import utils._ ...
想以絕對地址導入,在語句前增長root前綴:
@import _root_.company.product.core._
若是須要在全部template中導入,能夠在sbt中聲明全局配置:
TwirlKeys.templateImports += "org.abc.backend._"
以 @* *@ 包含的代碼塊將被視做註釋:
@********************* * This is a comment * *********************@
若是將註釋放在template的第一行,將生成Scala API doc:
@************************************* * Home page. * * * * @param msg The message to display * *************************************@ @(msg: String) <h1>@msg</h1>
默認,動態內容將根據模板類型進行自動轉義(如 HTML或者XML)。若是你但願展現原始內容,請將它們包裝金template content類型中。
下面的例子將輸出原生的HTML:
<p> @Html(article.content) </p>