通译:Play scala模板系统

翻译:Play scala模板系统

Scala templates

Play Scala comes with a new and really poweful Scala based template engine. The design of this new template engine is really inspired by ASP.NET Razor, especially:

Play Scala提供了一个新的、强劲的基于scala的模版引擎。新模版引擎的设计灵感来自于asp.net razor,特别是:

Compact, Expressive, and Fluid : Minimizes the number of characters and keystrokes required in a file, and enables a fast, fluid coding workflow. Unlike most template syntaxes, you do not need to interrupt your coding to explicitly denote server blocks within your HTML. The parser is smart enough to infer this from your code. This enables a really compact and expressive syntax which is clean, fast and fun to type.

简洁、有表现力、灵活:在文件中需要尽可能少的字符数和输入,取得更快的、更灵活的工作流程。不像大多数模板的语法,你不需要中断你的代码来明确指出html中的服务器blocks。解析器能够从你的代码中自动判断服务器blocks。从而得到真正简洁、有表现力的干净、快速、有趣的语法。

Easy to Learn : Enables you to quickly be productive with a minimum of concepts. You use all your existing Scala language and HTML skills.

好学:只有很少的概念,使你能很快用它进行工作。你只要用已有的scala语言和html技巧就可以了。

Is not a new language : We consciously chose not to create a new language. Instead we wanted to enable developers to use their existing Scala language skills, and deliver a template markup syntax that enables an awesome HTML construction workflow with your language of choice.

不是一门新语言:我们有意不去创造一门新的语言,而是想要开发者能够使用他们已有的scala语言、技巧,来实现一套能用你选择的语言完成漂亮的html流程的模板标记语法

Works with any Text Editor : Razor doesn’t require a specific tool and enables you to be productive in any plain old text editor.

可用任何编辑器工作:razor不需要一个特殊的工具,你能用任何普通的、原始的文字编辑器来工作。

Overview

概述

A Play Scala template is a simple text file text file, that contains small blocks of Scala code. It can generate any text-based format (HTML, XML, CSV, etc.).

一个play scala模板是一个简单的文本文件,包含小的scala代码块。它能生成任何基于文本的格式:html、xml、csv等等。

It’s particularely designed to feel comfortable to those used to working with HTML, allowing Web designers to work with.

它被专门设计成方便使用html来工作的。

They are compiled as standard Scala functions, following a simple naming convention:

模板被编译成标准的scala函数,下面是一个简单的命名惯例

If you create a views/Application/index.scala.html template file, it will generate a views.Application.html.index function.

如果你创建了 views/Application/index.scala.html 模板文件,它将生成一个views.Application.html.index 函数

Here is for example, a classic template content:

下面是一个模板内容的示例:

@(customer:models.Customer, orders:Seq[models.Order])
 
<h1>Welcome @customer.name!</h1>
 
@if(orders) {
     
    <h2>Here is a list of your current orders:</h2>
     
    <ul>
    @orders.map { order =>
        <li>@order.title</li>
    }
    </ul>
     
} else {
     
    <h2>You don't have any order yet...</h2>
     
}






And you can easily use it from any Scala code:

你能够轻松的在任何scala代码中使用它

val page:play.template.Html = views.Application.html.index(
    customer, orders
)






Syntax: the magic ‘@’ character

语法:神奇的@字符

 

The Scala template uses '@' as single special character. Each time this character is encountered, it indicates the begining of a Scala statement. It does not require you to explicitly close the code-block, and will infer it from your code:

scala模板用@作为唯一的特定字符。每当@出现,说明scala语句开始。你不需要专门支持代码块在哪里结束,模板将自动从你的代码中推断:

Hello @customer.name!
      ^^^^^^^^^^^^^^
        Scala code






Because the template engine will automatically detect the end of your code block by analysing your code, it only allow for simple statements. If you want to insert a multi-token statement, just make it more explicit using brackets:

因为模板引擎能自动分析你的代码来推测代码块结束的地方,所以只被允许使用一些简单的语句。如果你想插入一个多元运算的语句,可以使用括号来使它更明确

Hello @(customer.firstName + customer.lastName)!
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
                    Scala Code






You can also use curly bracket, like in plain Scala code, to write a multi-statements block:

你也可以用花括号,就像普通的scala代码一样,来写一个有多个语句的代码块

Hello @{val name = customer.firstName + customer.lastName; name}!
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                             Scala Code






Because '@' is the only special character, if you want to escape it, just use '@@'

因为@是唯一的特定字符,如果你想表示@,你要用"@@"

Template parameters

模板参数

Because a template is a function, it needs parameters. Template parameters must be declared on the first template line:

因为一个模板是一个函数,它需要参数。模板的参数必须在模板的第一行被声明

@(customer:models.Customer, orders:Seq[models.Order])






You can also use default values for parameters:

你也能给参数赋默认值:

@(title:String = "Home")






Or even several parameter groups:

或者有多个参数组:

@(title:String)(body: => Html)






And even implicit parameters:

甚至是隐式参数:

@(title:String)(body: => Html)(implicit session:play.mvc.Scope.Session)






Note that all parameter type names must be fully qualified.

注意:所有的参数类型都必须是完整的

Looping

循环

You can use the Scala for comprehension , is a pretty standard way. Just note that the template compiler will just add a yield keyword before your block:

你能用scala的for推导语句,这是一个相当标准的方法。只是要注意模板编译器会在你的代码块前加一个yield关键字

<ul>
@for(p <- products) {
    <li>@p.name ($@p.price)</li>
} 
</ul>






But as you probably know, here the for comprehension is just syntaxic sugar for a classic map:

但你可能知道,下面的这个for comprehension不过是个语法糖

<ul>
@products.map { p =>
    <li>@p.name ($@p.price)</li>
} 
</ul>






If-Blocks

Nothing special here. Just use the if instruction from Scala:

没有什么特别的,只是用scala里的if语句

@if(items.isEmpty) {
    <h1>Nothing to display</h1>
} else {
    <h1>@items.size items!</h1>
}






Pattern matching

模式匹配

You can also use pattern matching in templates:

你也能在模板中使用模式匹配

@connected match {
    
    case Admin(name) => {
        <span class="admin">Connected as admin (@name)</span>
    }
    
    case User(name) => {
        <span>Connected as @name</span>
    }
    
}






Declaring reusable blocks

声明重用模块

You can create reusable code block (or sub template):

你能创建重用模块(子模板)

@display(product:models.Product) = {
    @product.name ($@product.price)
}
 
<ul>
@products.map { p =>
    @display(product = p)
} 
</ul>






Note that you can also declare reusable pure Scala blocks:

你也可以声明纯scala的重用模块

@title(text:String) = @{
    text.split(' ').map(_.capitalize).mkString(" ")
}
 
<h1>@title("hello world")</h1>






Import statements

Import 语句

You can import whatever you want at the begining of your template (or of a sub template):

你可以在模板或子模板开头import库

@(customer:models.Customer, orders:Seq[models.Order])
 
@import utils._
 
…






Composing templates (tags, layouts, includes, etc.)

Templates being simple functions you can compose them in any way you want. Below are a few examples of other common scenarios:

模板是简单的函数,你能用任何任何你想的方式编写它们。下面是一些常见的写法的例子

Layout

Let’s declare a views/main.scala.html template that will act as main layout:

我们来定义一个views/main.scala.html模板作为主layout

@(title:String)(content: => Html)
 
<h1>@title</h1>
 
<hr>
 
<div id="main">
    @content
</div>
 
<hr>
 
<div id="footer">
    ...
</div>






As you see this template takes 2 parameters: a title and an HTML block.

这个模板有2个参数,一个标题,一个html块。

Now we can use it from another views/Application/index.scala.html template:

现在我们在另一个叫views/Application/index.scala.html的模板中使用它:

@main(title = "Home") {
    
    <h1>Home page</h1>
    
}






Tags

Let’s write a simple views/tags/notice.scala.html tag that display an HTML notice:

我们来写一个简单的views/tags/notice.scala.html tag显示一个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>
    }
    
}






And let’s use it from any template:

我们可以在任意的模板中使用它

@import views.tags.html._
 
@notice("error") { color =>
    Oops, something is <span style="color:@color">wrong</span>
}






Includes

Nothing special, you can just call any other templates:

没什么特别的,你能在一个模板中使用其它的模板

<h1>Home</h1>
 
<div id="side">
    @views.common.html.sideBar()
</div>