Play 2.0 用戶指南 - 模版引擎 -- 針對Scala開發者


一個基於Scala的類型安全的模版引擎


    Play2.0帶來了一個全新的真正強大的基於Scala的模版引擎。該引擎的設計靈感源於ASP.NET Razor.特別是:

        簡潔,富有表達力,流暢:最小化語法字符和擊鍵要求,讓你快速,流暢的編寫代碼。不像大多數模版引擎的語法,你無須明確的中斷HTML代碼就可嵌入服務器端邏輯。引擎會智能 的爲你識別。這是一個真正簡潔,富有表達力的語語法,使輸入變得乾淨,快速,愉快。html

        易於學習:掌握簡單的概念就能讓你快速產出。它使用你已掌握的Scala和HTML技能。
        非新語言:咱們極力避免創造一門新語言。相反,咱們想使開發人員可以利用其現有的Scala語言技能,在你選擇的語言下提供一個HTML結構工做流程的模板標記語法。
        可以使用任何文本編輯器:不須要特別的編輯工具,舊的文本編輯器也可輕鬆工做。

    模版會被編譯,所以你能夠在瀏覽器中看到任何編譯錯誤。

   

概述


    Play Scala 模版是簡單的文本文件,它包含簡短的Scala代碼塊。它能夠生成任何的文本格式,HTML,XML,CVS。
   模版系統已被設計成能夠天然溫馨的處理HTML,使得web設計師們能輕鬆的工做。

    模版會被編譯成標準的Scala函數,遵循簡單的命名約定:若是你建立了一個 views/Application/index.scala.html 模版文件,它將產生一個  views.html.Application.index 函數。
    例如,下面這個簡單的模版:
@(customer: Customer, orders: Seq[Order])
 
<h1>Welcome @customer.name!</h1>

<ul> 
@orders.map { order =>
  <li>@order.title</li>
} 
</ul>

    你能夠在你的任何Scala代碼中,像函數同樣調用它:
val html = views.html.Application.index(customer, orders)

語法:充滿魔力的‘@’字符


    Scala模版使用 @ 做爲單獨,特殊的字符。每當遇到該字符,即是指示這是Scala代碼塊的開始。不須要明確的關閉該代碼塊 - 模版會根據代碼自動推斷:
Hello @customer.name!
       ^^^^^^^^^^^^^
        Scala code


    由於模版引擎經過分析源碼自動檢測代碼塊結尾處,因此它僅僅支持簡單的聲明塊。若是你想插入多塊聲明,請明確的用括號標記:
Hello @(customer.firstName + customer.lastName)!
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
                    Scala Code


    你也能夠使用純正的Scala語法,使用大括號標記多塊聲明:
Hello @{val name = customer.firstName + customer.lastName; name}!
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                             Scala Code


    因爲 @ 是特殊字符,有時候你須要轉義。像這樣 @@ :
My email is bob@@example.com

    模版參數


    模版是一個普通函數,因此它須要參數,參數必須聲明在模版文件的第一行:
 
@(customer: models.Customer, orders: Seq[models.Order])
    你也能夠指定參數默認值:
@(title: String = "Home")
    或者甚至是參數組:
@(title:String)(body: => Html)
    甚至一個隱式參數:
    
@(title: String)(body: => Html)(implicit request: play.api.mvc.Request)

    迭代

    你能夠使用 Scala 的for-comprehension,以很表標的方式。但注意,編譯器會自動在你的代碼塊前面加上 yield 關鍵字:
<ul>
@for(p <- products) {
  <li>@p.name ($@p.price)</li>
} 
</ul>


    你可能意識到了,該for僅僅是經典的map形式的語法糖:
<ul>
@products.map { p =>
  <li>@p.name ($@p.price)</li>
} 
</ul>

    

    if塊

    if塊也沒什麼特別。簡單的使用標準的 Scala if 聲明:
@if(items.isEmpty) {
  <h1>Nothing to display</h1>
} else {
  <h1>@items.size items!</h1>
}


    模式匹配


    你也能夠在模版中使用模式匹配:
@connected match {
    
  case models.Admin(name) => {
    <span class="admin">Connected as admin (@name)</span>
  }

  case models.User(name) => {
    <span>Connected as @name</span>
  }
    
}


    定義可重用塊


    你能夠定義可重用代碼塊:
@display(product: models.Product) = {
  @product.name ($@product.price)
}
 
<ul>
@products.map { p =>
  @display(product = p)
} 
</ul>


    注意你也能夠用純Scala方式聲明可重用代碼塊:
@title(text: String) = @{
  text.split(' ').map(_.capitalize).mkString(" ")
}
 
<h1>@title("hello world")</h1>


    注意:這種方式聲明的代碼塊某些時候可能頗有用,但謹記,模塊不是一個編寫複雜邏輯的好地方。它一般都應該提取到外部的Scala文件中。(若是你願意,出能夠保存在views/目錄中)

    依照慣例,以 implicit 開頭的可重用塊會被標記爲 隱式的:
@implicitFieldConstructor = @{ MyFieldConstructor() }


    聲明可重用值


    你能夠使用 define 定義範圍變量值:
@defining(user.firstName + " " + user.lastName) { fullName =>
  <div>Hello @fullName</div>
}


    導入聲明


    你能夠在模版開頭(或子模塊)處按需導入聲明:
@(customer: models.Customer, orders: Seq[models.Order])
 
@import utils._
 
...


    註釋

    在服務器端編寫註釋,你能夠使用 @* *@:
@*********************
 * This is a comment *
 *********************@


    你能夠在第一行編寫註釋以Scala API的形式文檔化該模版。
@*************************************
 * Home page.                        *
 *                                   *
 * @param msg The message to display *
 *************************************@
@(msg: String)

<h1>@msg</h1>


    轉義


    默認狀況下,內容的動態部分會依照模版的類型轉義(如 HTML,XML)。若是你須要輸出原生的內容,請在模版中用模版內容類型包裝。

    如輸出原始的HTML    
<p>
  @Html(article.content)    
</p>


    Scala模版的常見用例


    模版,做爲普通函數,可經過任何方式組合。下面是一些經常使用的場景例子。

    佈局


    讓咱們聲明一個 views/main.scala.html 模版,它將做爲主要佈局模版: web

@(title: String)(content: Html)
<!DOCTYPE html>
<html>
  <head>
    <title>@title</title>
  </head>
  <body>
    <section class="content">@content</section>
  </body>
</html>

    你看到,該模版須要兩個參數:title 和 Html 內容塊。咱們能夠在另外一個 views/Application/index.scala.html 中使用它:
@main(title = "Home") {
    
  <h1>Home page</h1>
    
}

    注意:咱們有時命名參數爲@main(title = "Home"),有時候爲@main("Home")。依你所好,在不一樣的場景中選擇更簡潔的形式。

    有時候,你須要另外一個頁面特定的內容,例如邊欄或者頁腳。你能夠指定另外一個參數:
@(title: String)(sidebar: Html)(content: Html)
<!DOCTYPE html>
<html>
  <head>
    <title>@title</title>
  </head>
  <body>
    <section class="sidebar">@sidebar</section>
    <section class="content">@content</section>
  </body>
</html>


    在咱們的'index'模版中使用它,須要:
@main("Home") {
  <h1>Sidebar</h1>

} {
  <h1>Home page</h1>

}

    另外,咱們能夠單獨聲明邊欄:
@sidebar = {
  <h1>Sidebar</h1>
}

@main("Home")(sidebar) {
  <h1>Home page</h1>

}

    標籤(它們也不過是函數,不是嗎?)

    讓咱們編寫一個簡單的 views/tags/notice.scala.html 標籤,顯示HTML通知:

    如今,讓咱們在另外一個模版中使用它:
@(level: String = "error")(body: (String) => Html)
 
@level match {
    
  case "success" => {
    <p class="success">
      @body("green")
    </p>
  }

  case "warning" => {
    <p class="warning">
      @body("orange")
    </p>
  }

  case "error" => {
    <p class="error">
      @body("red")
    </p>
  }
    
}

    包含

    一樣,這也沒什麼特別。你能夠調用任何你須要的模版(其實是來自任何地方的函數均可以):
<h1>Home</h1>
 
<div id="side">
  @common.sideBar()
</div>
相關文章
相關標籤/搜索