动态标签库
Grails为JSP和GSP提供了很多内置的标签(见[标签参考]),同时grails也通过他的动态标签库机制提供创建各种自定义标签支持。
Grails的标签的好处在于他不需要任何额外的配置,不需要更新TLD描述,可以在不需要重启服务器进行重新装载。这让你感觉开发标签就像在开发一个页面一样简单,同时具有普通的页面10倍的用处。
| 警告 Grails 标签库需要一些额外的工作来集成到JSP里去,因为他的动态机制他能无缝的集成到GSP里,如果需要在JSP中使用请参考最后一节。 |
简单的标签
要创建一个新的标签,修改文件"grails-app/taglib/ApplicationTagLib.groovy",或者创建一个以"TagLib"结尾的新类。 要创建一个简单的标签只需要增加一个新的闭包(closure),这个闭包有一个参数,参数中包含了标签的所有属性:
@Property includeJs = { attrs ->
out << "<script xsrc='scripts/${attrs['script']}.js' />"
}
要在你的GSP中使用这个标签,只需要使用"g"这个前缀加闭包的名字即可:
<g:includeJs script="myscript" />
逻辑标签
要也可以创建逻辑判断的标签,创建一个使用两个参数的闭包,参数是标签的所有属性和标签的内容:
@Property isAdmin = { attrs, body ->
def user = attrs['user']
if(user != null && checkUserPrivs(user)) {
body()
}
}
上面的这个标签检查用户是否是管理员,如果是的话就显示标签内的内容:
<g:isAdmin user="${myUser}"> // 一些有访问权限控制的内容 </g:isAdmin>
迭代标签
当然,你也可以创建迭代(循环)类的标签:
@Property repeat = { attrs, body ->
def i = Integer.valueOf( attrs["times"] )
def current = 0
i.times {
body( ++current ) // pass the current iteration as the groovy default arg "it"
}
}
要调用你的标签你只需要:
<g:repeat times="3"> <p>Repeat this 3 times! Current repeat = ${it}</p> </g:repeat>
Markup building in tags
Grails provides a special method that allows building of markup (a common usecase in tags). To do so you invoke the 'mkp' method passing a closure with the markup you want rendered:
@Property dialog = { attrs, body ->
mkp {
div('class':'dialog') {
body()
}
}
}
Tags as method calls in GSP
GSP 标签也可以在GSP页面中使用Groovy表达式,例如,hasErrors这个标签可以像普通标签一样使用,如:
<g:hasErrors bean="${book}" field="title"> <span class='label error'>There were errors on the book title</span> </g:hasErrors>
也可以当方法调用,如:
<span id="title" class="label ${hasErrors(bean:book,field:'title','errors')}">Title</span>
方法的最后一个参数将被当作标签的标签体,或者你可以传入一个返回字符串的闭包:
<%=
hasErrors(bean:book,field:'title') {
'errors'
} %>
在JSP中使用Grails的标签库
要在JSP里使用Grails标签,你可以使用Grails标签库中定义的"invokeTag"标签:
<g:invokeTag name="includeJs" script="myscript" /> <g:invokeTag name="isAdmin" user="${myUser}"> // some restricted content </g:invokeTag > <g:invokeTag name="repeat" times="3"> <p>Repeat this 3 times! Current repeat = <c:out value="${it}" /></p> </g:invokeTag>
如果你希望你的标签看起来更想普通的JSP标签,你需要:
1) 创建一个新的java类继承 org.codehaus.groovy.grails.web.taglib.jsp.JspInvokeGrailsTagLibTag 并在构造函数中调用"setName()" 方法并传入你的标签名字:
package com.mycompany.taglib; public class IncludeJsTag extends JspInvokeGrailsTagLibTag { public static final String TAG_NAME = "includeJs"; public IncludeJsTag() { super.setName(TAG_NAME); } }
2) JSP 需要在TLD中为每个标签都进行声明,因此你必须根据你的需要修改文件 "web-app/WEB-INF/tld/grails.tld" ,加入你的声明:
<tag> <name>includeJs</name> <tag-class>com.mycompany.taglib.IncludeJsTag</tag-class> <body-content>JSP</body-content> <variable> <name-given>it</name-given> <variable-class>java.lang.Object</variable-class> <declare>true</declare> <scope>AT_BEGIN</scope> </variable> <dynamic-attributes>true</dynamic-attributes> </tag>
3) 现在,你可以在JSP中想普通的标签一样使用你的新标签了:
<g:includeJs script="myscript" />