现在几乎每个web语言都会有这样那样的模板供你选择,如果你曾经使用过任何一种模板,我想模板这个概念你能很清晰的阐明,我借用类与对象的关系进行阐述:模板的功能就是将(含有模板元素的)页面实例化输出。每个人对模板的概念都不一而同,但模板干的事情几乎都是一致的--渲染页面!
Play的模板在HTML基础上直接基于Scala语言,模板文件通常存放在/app/views目录下,文件须以“.scala.html”双扩展名命名。Play的每个模板文件其实都是一个Scala代码,均需要通过Scala编译器检查其类型与语法,并编译成.class可执行的JVM二进制文件。
编译时Play首相会将.scala.html的Play模板文件自动生成为.scala的源代码文件,如 /app/views/index.scala.html的模板文件将会生成/target/scala-2.9.1/src_managed/main/views/html/index.template.scala文件,该文件将会继而被Scala编译器编译成index.class。
首先看一下index.scala.html文件:
@(message: String)
@main("Welcome to Play") {
@play20.welcome(message)
}
我们可以先这么简单的理解:message是传入到@main(){}里的参数
那@main()... 是什么呢?--是在调用 main.scala.html 的模板!--我也是刚学的:),一切都明了了,就看看这个模板里写的是什么:
@(title: String)(content: Html)
<!DOCTYPE html>
<html>
<head>
<title>@title</title>
<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">
<link rel="shortcut icon" type="image/png" href="@routes.Assets.at("images/favicon.png")">
<script src="@routes.Assets.at("javascripts/jquery-1.9.0.min.js")" type="text/javascript"></script>
</head>
<body>
@content
</body>
</html>
很眼熟是吧,我们使用其他模板时候,也会经常和这个页面打交道吧!对,这就是要渲染的目标模板页面!
**现在是不是清晰明了了?但是我有个疑问:为什么要这么设计?为什么不能像Servlet那样setAttr..然后通过模板引擎获取值(getAttr..)之后直接渲染页面呢?这样跳来跳去的有什么好处呢?----先把这个疑问搁置一下。
**
在Play的模板中@符号代表跟随其后的代码为Scala语言代码,由于最终任何.scala.html文件都将转换成Scala语言代码,在编写Play模板时也可以理解为编写Scala语言代码,一个模板文件可以理解为一个对象,因此需要传入参数时就必须在模板文件的第一行定义都需要哪些入参以及这些入参的名字和类型。
服务器端的代码注释写法为: @* 注释内容 *@
看完之后,我好像明白了为什么Play会这么用模板了,中间那层index.scala.html是为了将Controller里传入的实参转化为:参数标记Key-value的形式,然后再调用模板实现页面渲染(Play中参数标记key并不像Beetl那样是字符串形式,而是默认参数次数 的形式!)。---难道Play的action不支持像Servlet那种set/getAttr..吗?还需要这么样的一个跳板?也许是我too young too simple!
Play模板传参的这种情况,不同于其他模板的实现,是使用默认参数顺序来构建的,这样就要求我们记住参数顺序,并且在渲染页面里顺序接受再使用。--经过询问高手,原来Play中把模板认为是scala object,所以安装这种方式来操作!--另外听说,Play不支持session,推荐使用cache管理session。
在后面的学习中,我们继续探究Play的模板机制吧!