【四 Twirl模板引擎】 1. 模板引擎

基於Scala的類型安全的模板引擎

Play提供了基於Scala的強大模板引擎Twirl。它的誕生靈感來自於 ASP.NET Razor。它有以下特色:html

  • 簡潔、流暢、富於表現力:它能讓你儘量少的打字,同時提供了一個快速流暢的編碼體驗。與不少其餘模板引擎不一樣之處在於在HTML中不會有服務端的代碼塊來打斷編碼節奏。聰明的解析器會自動推斷出指望的結果,這種好處帶來的直接後果就是簡潔而乾淨的代碼,快速,且富於樂趣。
  • 易上手:只包含了一些簡單的概念,讓你很快就能上手寫代碼。你可使用簡單的Scala結構和全部現有的HTML技能。
  • 不是一個新語言:咱們特地選擇了不創造一門新的語言。而儘量的保留了Scala語言的特性,經過模板標記語法來支持一個出色的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 塊

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() }

聲明重用的value

你可使用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>
相關文章
相關標籤/搜索