FreeMarkerのfunctionをjavaでつくってみる

FreeMarkerってべんりですよね!
functionとかmacroで簡単なロジックも書けたりとか!
でもなんかもうちょっとfunctionで色々やりたいとか思ったりもしますよね!しませんか!
ぼくはしたのでやってみました!


FreeMarker Manual - FAQ
FreeMarker Manual - Bean wrapper
このへんを軽く流し読みした限りだとTemplateMethodModelExを実装したクラスをConfiguration#setSharedVariableにぶちこめばいける雰囲気です。


その前にTemplateMethodModelっていうのもあってこれがTemplateMethodModelExと何が違うのかわかんないのでjavadocを見ます。
TemplateMethodModel (FreeMarker 2.3.20 API)
TemplateMethodModelEx (FreeMarker 2.3.20 API)
英語よくわかんないですけどなんか多分実装しないといけないexecメソッドの引数の型が違う感じっぽい。
TemplateMethodModelだと問答無用でStringが入ってくるけどTemplateMethodModelExだとちゃんと望んだ型で取れる的な。きっと。そんなかんじ。


今回はためしに引数として渡ってきたStringをStringEscapeUtils#escapeHtmlでエスケープして返すfunctionを作ってみます。
まずはTemplateMethodModelExの実装クラスを作ります。

public class HtmlEscapeUtil implements TemplateMethodModelEx {
	@Override
	public Object exec(List args) throws TemplateModelException {
		if(CollectionUtils.isEmpty(args)){
			throw new TemplateModelException("wrong size.");
		}
		Object arg0 = args.get(0);
		String str = null;
		if (arg0 instanceof TemplateScalarModel){
			str = ((TemplateScalarModel)arg0).getAsString();
		}
		return StringEscapeUtils.escapeHtml(str);
	}
}

javadocに記述がある通りTemplateMethodModelExにおけるexecの引数はTemplateModelのListです。
今回は引数がStringのはずなのでTemplateScalarModelのインスタンスであるかどうか確認して、正しければStringとして取得する形にしてます。
TemplateModelについては以下のjavadocを。
TemplateModel (FreeMarker 2.3.20 API)


次はこいつを実際に使えるようにしてやります。
今回のような拡張をしない場合、Springだとorg.springframework.web.servlet.view.freemarker.FreeMarkerConfigurerをbean定義してると思うんですが、今回はこいつを継承したクラスを作ります。

public class CustomFreeMarkerConfigurer extends FreeMarkerConfigurer {
	@Override
	public Configuration createConfiguration() throws IOException, TemplateException {
		Configuration config = super.createConfiguration();
		// TemplateMethodModelExを実装したクラスを「htmlEscape」としてセット
		config.setSharedVariable("htmlEscape", new HtmlEscapeUtil());
		return config;
	}
}

的な!感じで!
あとはこのクラスをFreeMarkerConfigurerの代わりにbean定義してやればあとはftlから呼び出すだけです!

${htmlEscape("<hoge>")}


いけた!すてきね!

スポンサーリンク