play框架用起来(9)

     

      Play具有高效的模板体系,采用Groovy作为其表达式语言,允许动态生成HTML、XML、JSON或者任何基于文本格式的文档,并且具有创建可重用标签(tag)的功能。模板储存在Play应用的app/views目录下。


1、模板语法

 与其他的语言一样,Play的模板也具有严格定义的语法。模板语法被划分为多种元素,用于完成不同类型的任务。Play模板的本质是普通的文本文件,其中带有占位符的部分可以生成动态内容。模板的动态部分采用Groovy语言编写,其语法与Java非常类似。框架可以将需要渲染的结果追加至HTTP响应的数据部分,并发送至模板。所有的动态部分将会在模板的执行期间被解析。 


(表1 模板语法)

元素 描述 语法
表达式 用于输出表达式的值。如 ${note.title} 的作用是将域对象note的属性title的值输出。 ${...}
标签 用于调用Play框架内置的或是开发人员自定义的标签。如#{get 'title' /}:获取变量 title 的值,该值仅在模板页面中有效。 #{...}
引用 用于生成调用控制器中Action方法的URL,在页面链接中使用的最为频繁。@{...} 和 @@{...} 的区别在于生成的URL分别是相对路径还是绝对路径。如:
1.<a href="@{Application.index()}">首页</a>:生成指向首页的链接。
2.@{'/public/stylesheets/main.css'}:引入CSS静态资源文件。
@{...} 和@@{...}
国际化 用于显示经过国际化处理后的消息内容。 &{...}
注释 用于在模板中添加注释。如:*{ 这是注释 }*。 *{...}*
脚本 用于添加复杂的 Groovy 脚本,可以声明变量和执行业务逻辑。 %{...}%

1.1 表达式(expression):${…}

      构建动态部分最简单的方法就是声明表达式。表达式需要以 ${ 开头, 并以 } 结尾,作为占位符使用。具体例子如下:

<h1>Client ${client.name}</h1>
      以上是输出客户姓名的表达式例子。在该例子中,将客户类定义为Client。经过控制器中Action的业务逻辑执行,首先需要向模板注入对象client,之后就可以在模板中使用${…}表达式语法输出client对象的name属性。

      如果不能确定向模板注入的client对象是否为null,可以使用如下Groovy快捷语法:

<h1>Client ${client?.name}</h1>
      此时,只有client不为null的情况下,才进行client.name的输出。


1.2 标签(tag): #{tagName /}#

      标签是能够附带参数调用的模板片段,如果标签只有一个参数,按照约定,参数的名称为arg,并且该参数名是可以省略的。例如,可以使用#{script}标签加载JavaScript文件:
#{script 'jquery.js' /}

      Play模板中的标签必须是闭合的,可以通过两种方式闭合标签。采用直接闭合的形式:

#{script  'jquery.js'/}
      或者起始标签和结束标签成对地使用:
#{script  'jquery.js'}#{/script}
      #{script}是Play模板的内置标签,由框架实现,可以直接使用。后面会进一步介绍如何自定义标签来满足开发中一些特定的需求。#{list}标签可以对集合类进行迭代操作,使用时需要注意,必须带有两个参数(items以及as):
<h1>Client ${client.name}</h1>
<ul>
    #{list items:client.accounts, as:'account' }
       
<li>${account}</li>
    #{/list}
</ul>
      上例中使用#{list}标签对client.accounts集合进行迭代,并将集合中的每一条数据作为account在页面中输出。

      在应用中,模板引擎默认对所有的动态表达式进行转义,以此来避免XSS的安全问题。如果模板中变量${title}的内容为<h1>Title</h1>,在页面输出时会自动进行转义:

${title} --> &lt;h1&gt;Title&lt;/h1&gt;

      也可以通过调用扩展方法raw(),以非转义的形式在页面中输出,具体使用方法如下:

${title.raw()} --> <h1>Title</h1>

      如果需要显示大量的非转义HTML内容,可以使用#{verbatim /}标签:

#{verbatim}
    $
{title} --> <h1>Title</h1>
#{/verbatim}


1.3 引用(action):@{…}或者@@{…}#

      在前面的章节已经有过一些介绍,Play通过路由器可以(逆向)生成URL,匹配指定的路由。在模板中使用@{…}引用可以达到相同的目的:

<h1>Client ${client.name}</h1>
<p>
   
<a href="@{Clients.showAccounts(client.id)}">All accounts</a>
</p>
<hr />

<a href="@{Clients.index()}">Back</a>
      该实例中,@{Clients.showAccounts(client.id)}调用了Clients控制器中的showAccounts Action方法,并传递了client.id参数。

      @@{…}引用的使用语法与@{…}相同,只不过生成的是绝对URL(尤其适用于邮箱)。

1.4 国际化(messages):&{…}#

      如果应用需要进行国际化操作,那么可以在模板中使用&{...}显示国际化信息。需要进行国际化的应用首先需要在conf/messages文件中进行国际化定义:

clientName=The client name is %s

      之后在模板中就可以通过&{...}显示该国际化信息了:

<h1>&{'clientName',client.name}</h1>

1.5 注释(comment):*{…}*#

      使用*{…}*标记的内容会被模板引擎忽略,起到注释作用:

*{**** Display the user name ****}*
<div class="name">
    $
{user.name}
</div>

1.6 脚本(script): %{…}%#

      脚本是更加复杂的表达式集合,能够声明一些变量或者定义一些语句。Play的模板中使用%{…}%插入脚本:

%{
fullName
= client.name.toUpperCase()+' '+client.forname;
}%
 
<h1>Client ${fullName}</h1>

      也可以直接使用out内置对象输出动态内容:

%{
   fullName
= client.name.toUpperCase()+' '+client.forname;
   
out.print('<h1>'+fullName+'</h1>');
}%

      在模板中还可以使用脚本编写结构化语句,执行一些逻辑操作,比如迭代:

<h1>Client ${client.name}</h1>
<ul>
%{
     for(account in client.accounts) {
}%
     
<li>${account}</li>
%{
     }
}%
</ul>

      使用模板时切记:模板不适合处理复杂的业务逻辑,所以在模板中请尽量使用标签,或者直接将处理交给控制器或模型对象。

  


2、模板继承

Play提供继承机制为多模板之间进行页面布局或设计提供服务。#{extends /} 和 #{doLayout /}可以使页面的共享和重用变得更加方便简洁,同时也能够帮助开发人员实现页面中动态内容和静态外观装饰的分离。在模板与装饰之间可以使用#{get}和#{set}标签进行参数传递。

      将simpledesign.html定义为父模板,也就是装饰模板。可以将页面中重用的静态内容定义在装饰模板中,如导航条、页面顶端的图片banner、页面底端的footer说明等。

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
   
<title>#{get 'title' /}</title>
   
<link rel="stylesheet" type="text/css" href="@{'/public/stylesheets/main.css'}" />
</head>

<body>
   
<h1>#{get 'title' /}</h1>
    #{doLayout /}
   
<div class="footer">Built with the play! framework</div>
</body>
</html>
      在simpledesign.html中将<head></head>、<h1></h1>、<div class="footer"></div>中的内容定义为公用元素,所有继承于该模板的页面都会包含这些内容。其中#{doLayout /}标签起到占位的作用,包含其子模板的页面内容。其他所有继承于simpledesign.html模板的页面内容都将显示在#{doLayout /}所占的页面区块。

      其他页面使用#{extends}标签可以非常简单地植入该装饰模板,具体使用方法如下:

#{extends 'simpledesign.html' /}
 
#{set title:'A decorated page' /}
This content will be decorated.
      该子模板使用#{extends 'simpledesign.html' /}标签来继承simpledesign.html,使用#{set title:'A decorated page' /}标签传递页面的title变量,最后在页面中输出This content will be decorated。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值