ダイナミック タグ ライブラリ
Grailsは、JSPとGSPのそれぞれのためにつくられた広範囲のカスタムタグを持っています (タグライブラリリファレンスを参照)。しかしながら、Grailsは、シンプルな動的タグライブラリメカニズムにより、簡単なタグ、論理的タグ、そしてイテレータ的なカスタムタグの開発も可能です。
| 寄贈! 他のGrails開発者と共有したいタグをお持ちの方は、寄贈してください! |
Grailsタグの利点は、付加的な設定項目やTLDディスクリプタの更新が必要なく、サーバの再起動することなくランタイムでオートリロードが可能なところです。これによりタグの開発があたかもビューの一部を開発していたかのように感じさせ、有益性を10倍にします。
| Warning Grailsタグライブラリは、JSPに組みこむにはちょっとした拡張作業を必要としますが、GSPに組みこむ場合にはシームレスかつ動的に行うことができます |
簡単なタグ
新しいタグをつくるためには、"grails-app/taglib/ApplicationTagLib.groovy"ファイルに追加編集する か、"TagLib"を最後に付けた新しいクラスを生成します。簡単なタグを定義するには、タグの属性値となる一つの引数をもつ新しいクロージャを追加し ます:
def includeJs = { attrs ->
out << "<script src='scripts/${attrs['script']}.js' />"
}
GSPページから上記タグを呼ぶためには、プレフィクス"g"とタグのプロパティ名を使用します:
<g:includeJs script="myscript" />
論理的タグ
また、タグ属性値とクロージャであるタグbodyからなる2つの引数をもつ、クロージャ構文を使って論理的タグを定義できます:
def isAdmin = { attrs, body ->
def user = attrs['user']
if(user != null && checkUserPrivs(user)) {
out << body()
}
}
上記タグはユーザが管理者であると判断されれば、タグのbodyを評価します:
<g:isAdmin user="${myUser}"> // some restricted content </g:isAdmin>
イテレータ的タグ
そしてもちろんイテレータ的なタグも定義できます:
def 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>
タグによるマークアップ生成
Grailsは、マークアップ生成が可能な特殊な方法を提供します。それを行うためには、表示したいマークアップを含むクロージャを引数とする'mkp'メソッドを呼び出します:
def dialog = { attrs, body ->
mkp {
div('class':'dialog') {
body()
}
}
}
GSPでの、メソッドコールとしてのタグ
GSPタグはまた、GSPページ内ではGroovy言語での記述が可能です。例えば、hasErrosタグは一般的には以下のようにタグとして使われます:
<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メソッドの最後の引数は、hasErrorsタグのbody部分が入ります。あるいはstringを返すクロージャを渡すことができます:
<%=
hasErrors(bean:book,field:'title') {
'errors'
} %>
JSPからGrailsタグライブラリを使うには
JSP内で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>
Grailsタグライブラリを、一般的なJSPタグのように記述したいなら、以下のようにする必要があります:
1) 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"ファイルを修正し、1)の追加クラスを表わす不可欠なエントリーを追加します:
<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タグのように、JSPから定義されたタグを使用することが可能になります:
<g:includeJs script="myscript" />