play框架手册04模板引擎Word格式.docx
《play框架手册04模板引擎Word格式.docx》由会员分享,可在线阅读,更多相关《play框架手册04模板引擎Word格式.docx(12页珍藏版)》请在冰点文库上搜索。
'
Adecoratedpage'
Thiscontentwillbedecorated.
decorator(母版)文件simpledesign.html的代码为:
htmlxmlns="
http:
//www.w3.org/1999/xhtml"
xml:
lang="
en"
lang="
>
head>
<
title>
#{get'
title'
/}<
/title>
linkrel="
stylesheet"
type="
text/css"
href="
@{'
/public/stylesheets/main.css'
}"
/>
/head>
body>
#{doLayout/}
divclass="
footer"
Builtwiththeplay!
framework<
/div>
/body>
/html>
Tags:
#{tagName/}
一个tag就是一个可以带参数的模板碎片,如果只有一个参数,则默认的参数名称就是arg,而且arg可以省略。
例如,如下的tag用于插入一个javascript脚本:
#{script'
jquery.js'
tag必须是关闭的:
或
}
#{/script}
例如,list标签用于迭代所有的集合元素,它带有两个必须的参数items和as:
ul>
#{listitems:
client.accounts,as:
account'
}
li>
${account}<
/li>
#{/list}
/ul>
所有的动态表达式将被模板引擎转义以避免XSS安全问题(XSS:
跨站脚本攻击),因此下列的title变量将被转义:
${title}-->
&
lt;
h1&
gt;
Title&
/h1&
如果不想转义,可以明确调用raw()方法:
${title.raw()}-->
Title<
当然,如果你想显示一个较多内容的rawhtml,你可以使用#{verbatim/}标签:
#{verbatim}
${title}-->
#{/verbatim}
Actions:
@{…}or@@{…}
可以使用Route来反向找到URL相应的特定route配置,在模板里,可以使用@{…}语法来完成这个任务,主要用于生成URL链接。
示例:
p>
ahref="
@{Clients.showAccounts(client.id)}"
Allaccounts<
/a>
/p>
hr/>
@{Clients.index()}"
Back<
//得到index()方法的链接
@@{…}语法与@{…}相似,不过它生成的绝对URL路径,对email很实用。
Messages:
{…}
&
{…}语法可用于国际化支持,以显示不同语言的消息:
例如在conf/messages目录下的文件里,我们可以这样定义:
clientName=Theclientnameis%s
在模板里使用时:
{'
clientName'
client.name}<
Comment:
*{…}*
注释部分将被模板引擎忽略:
*{****Displaytheusername****}*
name"
${user.name}
Scripts:
%{…}%
脚本是一段复杂的表达式集合,在脚本内可以声明变量和定义一些语句,play使用%{…}%来插入一段脚本。
%{
fullName=client.name.toUpperCase()+'
'
+client.forname;
}%
Client${fullName}<
在脚本里可以使用out对象直接输出动态内容:
out.print('
+fullName+'
);
在脚本里也可创建一个结构,比如用于迭代:
for(accountinclient.accounts){
请记住,模板不是一个放置复杂代码的好地方。
因此,请使用tag代替或放置在在controller或model对象里。
Templateinheritance继承
模板可以被继承,比如模板被作为另外一个模板的一部分而被包含进去。
要继承另一个模板,请使用#{extends‘…’}:
main.html'
Somecode<
main.html模板是一个标准模板,它使用doLayout标签来包含本模板的内容:
Maintemplate<
divid="
content"
定制模板标签
一个tag就是一个模板文件,存储于app/views/tags目录下,模板文件名将用作tag名称。
例如,创建一个hello标签,只需在app/views/tags/目录下创建一个hello.html文件,其内容如下:
Hellofromtag!
不需要任何配置,你就可以直接使用hello标签了:
#{hello/}
检索tag参数
tag参数默认被暴露为模板变量,变量名称带有‘_’字符前缀。
例如:
Hello${_name}!
现在你就可以给name变量传递参数了:
#{helloname:
Bob'
如果你的tag只有一个参数,默认的参数名称是arg,而且可以忽略。
Hello${_arg}!
使用更简单:
#{hello'
调用标签体
如果标签支持body,使用doBody标签,你就能在标签代码里的任何位置包含它。
比如:
Hello#{doBody/}!
然后你可使用这个名字作为标签体:
#{hello}
Bob
#{/hello}
格式化特定标签
你可以为不同的内容类型创建多个tag版本,play将自动选择适当的Tag。
例如,play将使用app/views/tags/hello.html来处理request.format为html的内容,使用app/views/tags/hello.xml来处理格式为xml的请求。
如果内容格式不匹配,play将返回一个app/views/tags/hello.tag的处理结果。
定制java标签
你也可以使用java代码来定义一个定制tags。
这和继承自play.templates.JavaExtensions类的JavaExtensions类相似,创建一个FastTag时,需要在类里创建一个方法,并且继承自play.templates.FastTags。
每一个要当作tag来执行的方法都必须遵循如下的方法签名:
publicstaticvoid_tagName(Map<
?
?
args,Closurebody,PrintWriterout,ExecutableTemplatetemplate,intfromLine)
注意:
tag名称之前必须要有下划线”_”。
为了理解如何创建一个真正的tag,让我们看一下两个内建的tags。
比如,verbatim标签仅通过简单调用JavaExtensions的toString()方法来实现的,并且被传递给tag的body。
publicstaticvoid_verbatim(Map<
args,Closurebody,PrintWriterout,ExecutableTemplatetemplate,intfromLine){
out.println(JavaExtensions.toString(body));
tag的body一定是在一对tag之间的(一开一关),即
verbatim>
Myverbatim<
/verbatim>
Body的值应该是
Myverbatim
第二个示例是option标签,要复杂一点,因为这个标签依赖于其父标签来实现相关功能。
publicstaticvoid_option(Map<
args,Closurebody,PrintWriterout,
ExecutableTemplatetemplate,intfromLine){
Objectvalue=args.get("
arg"
Objectselection=TagContext.parent("
select"
).data.get("
selected"
booleanselected=selection!
=null&
value!
=null
selection.equals(value);
out.print("
optionvalue=\"
"
+(value==null?
"
:
value)+"
\"
+(selected?
selected=\"
selected\"
)
+"
+serialize(args,"
"
value"
)+"
/option>
这些代码将输出一个标准的htmloption标签,并依据父标签的值设置为相应的option为selected,前三行用于设置用于输出的变量。
最后三行输出tag的结果。
在FastTags.javaingithub里有不同难度的标签示例。
标签命名空间
请检查你的tag在项目或与play标签之间没有冲突,你可以使用类级别的注释@FastTags.Namespace来设置命名空间。
因此,对hello标签来说,可以如下设置(空间名称为my.tags)
@FastTags.Namespace("
my.tags"
publicclassMyFastTagextendsFastTags{
publicstaticvoid_hello(Map<
...
之后在模板里用如下方式进行调用。
#{my.tags.hello/}
在模板里的Java对象扩展
当你在模板引擎里使用一个java对象时,play为其加入了一些新的方法,这些方法在原始的java类里并不存在,而是被模板引擎动态加入到模板里的,play对一些基本的java原始类进行了扩展。
例如,为了方便在模板里对数字进行格式化,play在java.lang.Number里增加了一个format方法:
之后,我们在模板里就很容易对一个数字进行格式化:
#{listitems:
products,as:
product'
${product.name}.Price:
${product.price.format('
#####,00'
)}€<
#{/list}
同样可用于java.util.Date
具体的内容见Javaextensions,它列出了一些扩展了的方法,如下:
对集合的扩展:
join(‘/’)用/进行连接后返回
last()返回最后一个元素
pluralize()是否大于1个,大于则返回一个字符串:
集合名+s
pluralize(plural)是否大于1个,大于则返回一个字符串:
集合名+plural指定的字符串,如es
pluralize(singular,plural)为1则返回集合名+singular指定的字符串,不为1则返回集合名+plural指定的字符串
对Date的扩展:
Format(foramt)返回格式化后的日期,如newDate().format(‘ddMMMMyyyy))
Format(format,language)带语言,如newDate().format(‘ddMMyy’,’en’)
Since()
Since(condition)
另外还对Long、Map、Number、对象、String、String数组等类型进行扩展。
创建定制扩展
只需要创建一个继承了play.templates.JavaExtensions的类即可。
例如,创建一个定制数字格式化的方法:
packageext;
importplay.templates.JavaExtensions;
publicclassCurrencyExtensionsextendsJavaExtensions{
publicstaticStringccyAmount(Numbernumber,StringcurrencySymbol){
Stringformat="
+currencySymbol+"
#####.##"
;
returnnewDecimalFormat(format).format(number);
每个扩展方法都是一个static方法,而且要返回一个java.lang.String结果,以便于在页面里显示。
第一个参数将用于保存扩展后的对象。
使用方法如下:
em>
Price:
${123456.324234.ccyAmount()}<
/em>
模板扩展类会被play自动加载,你只需要重启你的应用程序即可。
模板里可以使用的保留对象
所有添加到renderArgs作用域的对象都将直接注入成模板变量。
例如,从controller向模板注入一个userbean:
renderArgs.put("
user"
user);
在一个action里渲染模板里时,框架会自动添加以下保留对象:
Variable
Description
APIdocumentation
Seealso
errors
Validationerrors
play.data.validation.Validation.errors()
ValidatingHTTPdata
flash
Flashscope
play.mvc.Scope.Flash
Controllers-Session&
FlashScope
lang
Thecurrentlanguage
play.i18n.Lang
SettingupI18N-Definelanguages
messages
Themessagesmap
play.i18n.Messages
SettingupI18N-Externalizemessages
out
Theoutputstreamwriter
java.io.PrintWriter
params
Currentparameters
play.mvc.Scope.Params
Controllers-HTTPparameters
play
Mainframeworkclass
play.Play
request
ThecurrentHTTPrequest
play.mvc.Http.Request
session
Sessionscope
play.mvc.Scope.Session
以上列出的名称和owner/delegate/it在Groovy里是默认的保留字,在创建变量时要注意回避。