前回、mustache.javaでのテンプレートの書き方について記載しましたが、Javaコード側の内容についていくつか。
バインドできる項目
以下の項目でバインドするようです。
- パッケージスコープ以上のフィールド名(privateは不可)
- メソッド名(getter含む?)
- Mapのキー
例えば、テンプレート側で
{{message}}
とバインドさせたい時、Java側では以下のような書き方ができます。
String message = "Hello World";
あ、別にpublicでもprotectedでもOKです。要はprivateでなければ。
それから、メソッド
public String message() { return "Hello World"; }
メソッドも、privateでなければOKみたいです。
一応、getterも大丈夫そう
String message = "Hello World"; String getMessage() { return message; }
この場合、メソッドが呼ばれているようです。
あとは、Mapを直接バインドする、ですかね。
MustacheFactory mf = new DefaultMustacheFactory(); Mustache mustache = mf.compile("template/simple-template.mustache"); Map<String, String> map = new HashMap<>(); map.put("message", "Hello World"); mustache.execute(new PrintWriter(System.out), map).flush();
余談ですが、以下のようにCallableを返すようにした上で、MustacheFactoryにExecutorServiceを設定してあげることで、別スレッドで実行することも可能になるようです。
Callable<String> message() throws InterruptedException { return new Callable<String>() { @Override public String call() throws Exception { return "Hello World"; } }; }
テンプレートの場所の指定について
今まで、以下のように指定していた読み込むテンプレートの指定ですが
Mustache mustache = mf.compile("template/simple-template.mustache");
これの検索順は、クラスパス、実ファイルパスの順のようです。
com.github.mustachejava.DefaultMustacheFactoryより
@Override public Reader getReader(String resourceName) { ClassLoader ccl = Thread.currentThread().getContextClassLoader(); InputStream is = ccl.getResourceAsStream( (resourceRoot == null ? "" : resourceRoot) + resourceName); if (is == null) { File file = fileRoot == null ? new File(resourceName) : new File(fileRoot, resourceName); if (file.exists() && file.isFile()) { try { is = new FileInputStream(file); } catch (FileNotFoundException e) { throw new MustacheException("Found file, could not open: " + file, e); } } } if (is == null) { throw new MustacheException("Template '" + resourceName + "' not found"); } else { return new BufferedReader(new InputStreamReader(is, Charsets.UTF_8)); } }
ここで、fileRootはDefaultMustacheFactoryクラスのコンストラクタで指定できるルートディレクトリですが、クラスパスから読む場合には無視されます。