日期:2014-05-20  浏览次数:21035 次

Play framework 2.0 -模板引擎

#模板引擎

?

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() ($@p.getPrice())</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() ($@product.getPrice())
}
 
<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>
?