Velocity vs. FreeMarker

JavaのテンプレートエンジンとしてはFreeMarkerを愛用しているのだけど,サイトが今年になってからアップデートされていなかったり,やっぱり世間的にはVelocityであろう,という声もあり,Velocityも調べてみた.

Velocity

VelocityApacheのプロジェクト.かつてはJakartaの一部だったようだが,現在は違う.Velocityプロジェクトには,テンプレートエンジンであるEngineの他にもAnakia, Taxen, DocBook, DVSLのサブプロジェクトがある.ちなみにVelocity EngineというとPowerPCプロセッサのSSEのようなものの名前らしいので,紛らわしい.

Velocityのダウンロードと使用

ダウンロードは上述サイトから.バイナリパッケージのルートにjarが二つはいっており,それらを配備するだけで使える.App Engineでは,war/WEB-INF/libに配備する.

App Engineでの使い方はこんな感じ.

try {
  Velocity.setProperty(
    Velocity.RUNTIME_LOG_LOGSYSTEM, new JdkLogChute());
  Velocity.init();
} catch (Exception e1) {
  e1.printStackTrace();
}
VelocityContext context = new VelocityContext();
context.put("user", user);
...

try {
  Template template = 
    Velocity.getTemplate("WEB-INF/greetings.vm");
  resp.setContentType("text/html");
  resp.setCharacterEncoding("utf-8");
  template.merge( context, resp.getWriter() );
} catch (Exception e) {
  e.printStackTrace();
}

例外をExceptionでキャッチしているのはサボっているわけではなくて,ほんとうにExceptionでインターフェイスが定義されているから.なんてお行儀の悪い...

面倒だったのは,ログの指定.App Engineではjdkのloggerを使うのは標準なのでこのJdkLogChuteを用いる.

  Velocity.setProperty(
    Velocity.RUNTIME_LOG_LOGSYSTEM, new JdkLogChute());

FreeMarkerとの相違点としては,特殊なContextオブジェクトを使っている点が挙げられる.FreeMarkerは普通のMapだ.

テンプレート

テンプレートのdirectiveとしては,FreeMarkerXML風のタグを使うのに対して,Velocityはタグっぽくない.これは善し悪しか.

下記はVelocity.

#if ($greetings.size() == 0) 
  <p>The guestbook has no messages.</p>
#else
  #foreach ($g in $greetings)
    #if ($g.author)
      <p><b>$g.author.nickname</b> wrote:</p> 					
    #else
      <p>An anonymous person wrote:</p>			
    #end
    <blockquote>$g.content</blockquote>	
    #if ($g.tags)
      <div>
        #foreach ($tag in $g.tags)
          <span> $tag </span>
        #end
      </div>
    #end
  #end
#end

下記はFreeMarker.

<#if greetings?size == 0 >
  <p>The guestbook has no messages.</p>
<#else>
  <#list greetings as g >
    <#if g.author?? >
      <p><b>${g.author.nickname}</b> wrote:</p> 					
    <#else>
      <p>An anonymous person wrote:</p>			
    </#if>
    <blockquote>${g.content}</blockquote>	
    <#if g.tags?? >
      <div><#list g.tags as tag ><span> ${tag} </span></#list></div>
    </#if>
  </#list>	
</#if>

所感

テンプレート言語の表現力という意味ではほぼ等価なのかな.FreeMarkerがんばってほしいのだけど.

仕様をみると,Velocityは,テンプレートの「本分」を離れて独立したスクリプト言語になることを指向しているような気がしてならない.実際Velocity プロジェクトのtexenは,テンプレートを階層化して,メインテンプレートが,サブテンプレートを駆動するスタイルになっていて,呼び出し言語が存在しなかったり.これでいいのか?JSPとかPHPみたいに不細工なものになると困るのだけど.