#模板引擎
1.基于Scala的类型安全的模板引擎
Play2.0的有个新的基于Scala的十分强大的模板引擎,它的设计灵感来自于ASP.NET的Razor。
具体来说:
a.紧凑、表现力、流畅:它最大限度的减少了一个文件中所需字符和按键的数量,使得可以快速流畅的编码。
不像大多数模板语法,你不需要打断你的编码,在HTML中来显示的表明服务代码块。
解析器能聪明的推断出它们。这使得代码紧凑,语法干净流畅,编码快速、有趣。
b.容易学习:它可以用最少的概念让你迅速成为生产力。您可以使用简单的Scala的结构和所有现有的HTML技能。
c.不是一种新的语言:我们有意识地选择了不创造一门新的语言。相反,我们想使Scala开发人员可以使用他们现有的Scala语言技能,
并提供一个模板标记的语法,使HTML构建工作流程。
d.任何文本编辑器中编辑:它不需要特定的工具,使您能够使用任何普通的文本编辑器都很有工作效率。
注意:尽快模板引擎使用Scala作为表现语言,但这对于Java开发者并不是问题。你尽可以把Scala当Java来使用。
记住,模板中不是写复杂逻辑的地方,不应该在模版里写复杂的Scala代码。
使用后缀语法定义参数类型。泛型类型定义使用[]符号,而不是通常Java语法中的<> 。例如,你写的List[String],与Java中的List<String>是相同的。
2.概述
Play的Scala模板是个包含了小块Scala代码的简单文本文件。模板可以生成任意的文本格式,如HTML,XML或CSV。
模板系统是为了HTML开发者能舒服的工作,允许前后端开发这容易使用模板而设计的。
模板根据一个简单的命名规约被编译为标准的Scala函数。如果你创建了一个views/Application/index.scala.html的模板文件,
那么它会生成一个包含一个render()方法的类-views.html.Application.index。
下面是一个简单的模板:
@(customer: Customer, orders: List[Order])
<h1>Welcome @customer.name!</h1> <ul> @for(order <- orders) { <li>@order.getTitle()</li> } </ul>
你可以向通常在类里调用方法一样使用任意的Java代码调用它:
Content html = views.html.Application.index.render(customer, orders);
3.语法:神奇的‘@’
Scala模板用@作为一个特殊字符。每次当这个字符出现,就表明是动态语句的开始。你无需显式的关闭代码块,模板能够自动推断你代码的结尾。
因为模板引擎会通过分析你的代码自动检测你的代码块的结束,此语法仅支持简单的语句。如果你想插入一个多标记的语句,显式地使用括号标记:
Hello @(customer.getFirstName() + customer.getLastName())! Hello @{val name = customer.getFirstName() + customer.getLastName(); name}!
@是个特俗字符,如果你想使用它,可以使用两个@(@@)对它做一下转移:
My email is bob@@example.com
4.模板参数
模板就像函数,所以它也需要参数,参数要在模板文件的顶部声明。
@(customer: models.Customer, orders: List[models.Order])
也可是用默认的值设置参数
@(title: String = "Home")
或者甚至若干个参数组
@(title:String)(body: Html)
5.迭代
可以使用for关键字,用漂亮的标准方式:
<ul> @for(p <- products) { <li>@p.getName() ([email protected]())</li> } </ul>
6.if语句块
if块没什么特殊的,简单的使用Scala的标准if语句:
@if(items.isEmpty()) { <h1>Nothing to display</h1> } else { <h1>@items.size() items!</h1> }
7.申明可重用模块
用下面的代码创建可复用代码块:
@display(product: models.Product) = { @product.getName() ([email protected]()) } <ul> @for(product <- products) { @display(product) } </ul>
也可以什么纯代码可复用模块:
@title(text: String) = @{ text.split(' ').map(_.capitalize).mkString(" ") } <h1>@title("hello world")</h1>
注意:在模版中以这样的方式申明代码块有时候很有用,但是记着,模板不是写复杂逻辑的最佳地方。
把它写在Java类中通常更好。
8.声明可复用值
可以用defining帮助定义作用域值:
@defining(user.getFirstName() + " " + user.getLastName()) { fullName => <div>Hello @fullName</div> }
9.导入语句
可以在模板或字模板的开头导入任意东西:
@(customer: models.Customer, orders: List[models.Order]) @import utils._
10.注释
使用@* *@为Server端的代码块添加注释。
11.转义
默认的动态部分根据模板类型的规则被转义。如果你想输出一段原始内容,就用模板的类型包装它:
<p> @Html(article.content) </p>
#常见的模板用例
模板,也就是简单的函数,可以以你想要的任意方式构成。下面是一些常见的场景的几个例子。
1.布局
我们声明一个模板views/main.scala.html,作为主要布局模板:
@(title: String)(content: Html) <!DOCTYPE html> <html> <head> <title>@title</title> </head> <body> <section class="content">@content</section> </body> </html>
正如你所见,这个模板有两个参数,一个头title和一个HTMLcontent块。,现在我们看看另外一个模板:
@main(title = "Home") { <h1>Home page</h1> }
有时你需要一个第二页的具体内容块显示侧栏或导航,例如,你可以增加一个额外的参数:
@(title: String)(sidebar: Html)(content: Html) <!DOCTYPE html> <html> <head> <title>@title</title> </head> <body> <section class="content">@content</section> <section class="sidebar">@sidebar</section> </body> </html>
在我们的index模板中是使用它:
@main("Home") { <h1>Sidebar</h1> } { <h1>Home page</h1> }
或者,我们可以单独声明侧栏块:
@sidebar = { <h1>Sidebar</h1> } @main("Home")(sidebar) { <h1>Home page</h1> }
2.标签
写一个简单的标签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> } }
在其他模板中使用该模板:
@import tags._ @notice("error") { color => Oops, something is <span style="color:@color">wrong</span> }
3.包含(includes)
这里也一样没什么特殊的。你完全可以调用任何你喜欢的模板(或者叫函数吧,随便啦)。
<h1>Home</h1> <div id="side"> @common.sideBar() </div>