Groovyが提供しているテンプレートエンジン:
検証環境:
Win7 64bit JDK 1.7 64bit Groovy 1.8.9
GStringTemplateEngineでは、テンプレートテキストは "groovy.tmp.templates.GStringTemplateScript[N]"([N]にはインクリメントされる数字が入る)のclosure内で処理されます。テンプレート内で
<%= dump() %> <%= inspect() %>
すると以下のように出力されます。
↓↓"<%= dump() %>"の出力
<groovy.tmp.templates.GStringTemplateScript9$_getTemplate_closure1@73b05494 \
delegate=groovy.lang.Binding@3d80fbe2 \
owner=groovy.tmp.templates.GStringTemplateScript9@5f18d1f9 \
thisObject=groovy.tmp.templates.GStringTemplateScript9@5f18d1f9 ...
↓↓"<%= inspect() %>"の出力
groovy.tmp.templates.GStringTemplateScript9$_getTemplate_closure1@73b05494
ということで、
def binding = [
title : "...",
c : { s -> ... },
とした場合、テンプレート中で
<%= c(title) %>
としても、「groovy.tmp.templates.GStringTemplateScript[N]にはc()なんてメソッドありません」とエラーになります。
これを回避するには、以下のように"call()"メソッドで明示的にclosureを呼び出します。
<%= c.call(title) %>
例:
@Grapes([
@Grab(group='org.apache.commons', module='commons-lang3', version='3.1'),
])
import org.apache.commons.lang3.*
String input_s = "<hello, 'bonjour' & \"evening\">"
def binding = [
title : input_s,
h1 : { s -> StringEscapeUtils.escapeHtml4(s).replace("'", ''') },
h2 : { s ->
s.toString().replace('&', '&').replace('<', '<')
.replace('>', '>').replace('"', '"').replace("'", ''')
},
]
println binding.h1(input_s)
println binding.h2(input_s)
def engine = new groovy.text.GStringTemplateEngine()
def text = '''\
Raw Title : [<%= title %>]
HTML Escaped Title(1) : [<%= h1.call(title) %>]
HTML Escaped Title(2) : [<%= h2.call(title) %>]
'''
def template = engine.createTemplate(text).make(binding)
println template.toString()
実行結果:
<hello, 'bonjour' & "evening"> <hello, 'bonjour' & "evening"> Raw Title : [<hello, 'bonjour' & "evening">] HTML Escaped Title(1) : [<hello, 'bonjour' & "evening">] HTML Escaped Title(2) : [<hello, 'bonjour' & "evening">]
もう一つの方法は、"Object"クラスにテンプレートから使いたいメソッドをmixinしてしまう方法です。
@Grapes([
@Grab(group='org.apache.commons', module='commons-lang3', version='3.1'),
])
import org.apache.commons.lang3.*
String input_s = "<hello, 'bonjour' & \"evening\">"
class Helper {
String h1(String s) { StringEscapeUtils.escapeHtml4(s).replace("'", ''') }
String h2(String s) {
s.toString().replace('&', '&').replace('<', '<')
.replace('>', '>').replace('"', '"').replace("'", ''')
}
}
Object.mixin(Helper)
def binding = [
title : input_s,
]
println h1(input_s)
println h2(input_s)
def engine = new groovy.text.GStringTemplateEngine()
def text = '''\
Raw Title : [<%= title %>]
HTML Escaped Title(1) : [<%= h1(title) %>]
HTML Escaped Title(2) : [<%= h2(title) %>]
'''
def template = engine.createTemplate(text).make(binding)
println template.toString()
実行結果:
<hello, 'bonjour' & "evening"> <hello, 'bonjour' & "evening"> Raw Title : [<hello, 'bonjour' & "evening">] HTML Escaped Title(1) : [<hello, 'bonjour' & "evening">] HTML Escaped Title(2) : [<hello, 'bonjour' & "evening">]