home ホーム search 検索 -  login ログイン  | reload edit datainfo version cmd icon diff delete  | help ヘルプ

Groovy/TemplateEngine/GroovyTemplates

Groovy/TemplateEngine/GroovyTemplates

Groovy / TemplateEngine / GroovyTemplates
id: 1168 所有者: msakamoto-sf    作成日: 2013-03-23 21:32:56
カテゴリ: Groovy 

Groovyが提供しているテンプレートエンジン:

GStringTemplateEngineのTips

検証環境:

Win7 64bit
JDK 1.7 64bit
Groovy 1.8.9

Closureをbindしてテンプレートから使うには(1) : call()で明示的に呼ぶ

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("'", '&#39;') },
    h2 : { s ->
        s.toString().replace('&', '&amp;').replace('<', '&lt;')
        .replace('>', '&gt;').replace('"', '&quot;').replace("'", '&#39;')
        },
]
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()

実行結果:

&lt;hello, &#39;bonjour&#39; &amp; &quot;evening&quot;&gt;
&lt;hello, &#39;bonjour&#39; &amp; &quot;evening&quot;&gt;
Raw Title : [<hello, 'bonjour' & "evening">]
HTML Escaped Title(1) : [&lt;hello, &#39;bonjour&#39; &amp; &quot;evening&quot;&gt;]
HTML Escaped Title(2) : [&lt;hello, &#39;bonjour&#39; &amp; &quot;evening&quot;&gt;]

Closureをbindしてテンプレートから使うには(2) : Object.mixinする

もう一つの方法は、"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("'", '&#39;') }
    String h2(String s) {
        s.toString().replace('&', '&amp;').replace('<', '&lt;')
            .replace('>', '&gt;').replace('"', '&quot;').replace("'", '&#39;')
    }
}
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()

実行結果:

&lt;hello, &#39;bonjour&#39; &amp; &quot;evening&quot;&gt;
&lt;hello, &#39;bonjour&#39; &amp; &quot;evening&quot;&gt;
Raw Title : [<hello, 'bonjour' & "evening">]
HTML Escaped Title(1) : [&lt;hello, &#39;bonjour&#39; &amp; &quot;evening&quot;&gt;]
HTML Escaped Title(2) : [&lt;hello, &#39;bonjour&#39; &amp; &quot;evening&quot;&gt;]


プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2013-03-23 22:03:49
md5:0e7bbc9010d9641f3708e9fec3219c30
sha1:454b54cbc8b954085131f5c60a895058870a5d61
コメント
コメントを投稿するにはログインして下さい。