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>