最近、仕事でVelocityを使っていまして、その時にテンプレートの一部を評価しないみたいなことができないかなーと思って調べてみました。
Webアプリの画面テンプレートに使っているので、jQueryの
$('#id');
みたいな表記と、すごい相性悪いわけで…。
まあ、なんでVelocity使ってるの?なんでFreeMarkerじゃないの?とかいう話もあるかと思いますけど、今回はVelocityなんですよ。
で、やりたいことはFreeMarkerのnoparseディレクティブ的なことですね。
http://freemarker.sourceforge.net/docs/ref_directive_noparse.html
<#noparse> <#list animals as being> <tr><td>${being.name}<td>${being.price} Euros </#list> </#noparse>
Velocityにも、調べてみたらありました。
http://velocity.apache.org/engine/releases/velocity-1.7/vtl-reference-guide.html
こんなVTLらしいです。
#[[ ... #]]
Velocity 1.7からの機能みたいです。2010年リリースとはいえ、最新版で入った機能なんですねー。
http://velocity.apache.org/news.html#engine17
せっかくなので、FreeMarkerと合わせて使ってみました。
build.gradle
apply plugin: 'java' apply plugin: 'application' group = 'littlewings' version = '0.0.1-SNAPSHOT' mainClassName = "TemplateEngineNoParse" repositories { mavenCentral() } dependencies { compile 'org.apache.velocity:velocity:1.7' compile 'org.freemarker:freemarker:2.3.19' }
FreeMarkerテンプレート。
src/main/resources/template.ftl
My Name is ${name}!! Say, [${keyword}] ------------------------------ <#noparse> My Name is ${name}!! Say, [${keyword}] </#noparse>
Velocityテンプレート。
src/main/reslate.vm
My Name is ${name}!! Say, [${keyword}] ------------------------------ #[[ My Name is ${name}!! Say, [${keyword}] ]]#
両方とも、同じ意味のテンプレートで、前半後半でパースする方としない方に分かれています。
Javaソースコード。
src/main/java/TemplateEngineNoParse.java
import java.io.IOException; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import freemarker.cache.ClassTemplateLoader; import freemarker.template.Configuration; // import freemarker.template.Template; import freemarker.template.TemplateException; import org.apache.velocity.VelocityContext; // import org.apache.velocity.Template; import org.apache.velocity.app.Velocity; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.MethodInvocationException; public class TemplateEngineNoParse { public static void main(String[] args) { evalFreeMarker(); evalVelocity(); } public static void evalFreeMarker() { System.out.println("================== FreeMarker Start =================="); Configuration config = new Configuration(); config.setTemplateLoader( new ClassTemplateLoader( TemplateEngineNoParse.class, "")); try { freemarker.template.Template template = config.getTemplate("template.ftl"); StringWriter writer = new StringWriter(); template.process(createBindData(), writer); System.out.println(writer.toString()); } catch (IOException | TemplateException e) { e.printStackTrace(); } System.out.println("================== FreeMarker End =================="); } public static void evalVelocity() { System.out.println("================== Velocity Start =================="); Velocity.setProperty("resource.loader", "classpath"); Velocity.setProperty("classpath.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); Velocity.init(); VelocityContext context = new VelocityContext(); for (Map.Entry<String, String> entry : createBindData().entrySet()) { context.put(entry.getKey(), entry.getValue()); } try { org.apache.velocity.Template template = Velocity.getTemplate("template.vm"); StringWriter writer = new StringWriter(); template.merge(context, writer); System.out.println(writer.toString()); } catch (ResourceNotFoundException | ParseErrorException | MethodInvocationException e) { e.printStackTrace(); } System.out.println("================== Velocity End =================="); } public static Map<String, String> createBindData() { Map<String, String> data = new HashMap<>(); data.put("name", "Kazuhira"); data.put("keyword", "Hello Template Engine!!"); return data; } }
おおちゃくしてFreeMarkerとVelocityを両方書いたら、Templateのクラス名が被った…。
実行結果。
$ gradle --daemon run :compileJava UP-TO-DATE :processResources UP-TO-DATE :classes UP-TO-DATE :run ================== FreeMarker Start ================== My Name is Kazuhira!! Say, [Hello Template Engine!!] ------------------------------ My Name is ${name}!! Say, [${keyword}] ================== FreeMarker End ================== ================== Velocity Start ================== My Name is Kazuhira!! Say, [Hello Template Engine!!] ------------------------------ My Name is ${name}!! Say, [${keyword}] ================== Velocity End ================== BUILD SUCCESSFUL Total time: 2.295 secs
ちゃんと、動いてそうですね。