CLOVER🍀

That was when it all began.

mustache.javaをGroovyで使う

mustacheにはGroovy版はありませんが、そのままJava向けのmustache.javaが使えます。

mustache.javaではMapのキーが使えることを考えると、MapとListでけっこう簡単にバインドするオブジェクトを表現することができます。

例えば、mustache.javaのサンプルでJavaがこうなっていたのが

public class Context {
  List<Item> items() {
    return Arrays.asList(
      new Item("Item 1", "$19.99", Arrays.asList(new Feature("New!"), new Feature("Awesome!"))),
      new Item("Item 2", "$29.99", Arrays.asList(new Feature("Old."), new Feature("Ugly.")))
    );
  }

  static class Item {
    Item(String name, String price, List<Feature> features) {
      this.name = name;
      this.price = price;
      this.features = features;
    }
    String name, price;
    List<Feature> features;
  }

  static class Feature {
    Feature(String description) {
       this.description = description;
    }
    String description;
  }
}

Groovyでは、MapとListのリテラルを使用すると、ぐっと短くなります。

  static def createContext() {
    [items: [
            [name: 'Item 1', price: '$19.99', features: [
                    [description: 'New!'], [description: 'Awesome!']]],
            [name: 'Item 2', price: '$29.99', features: [
                    [description: 'Old.'], [description: 'Ugly.']]]
    ]]
  }

テンプレートは、もちろん同じもの。

{{#items}}
Name: {{name}}
Price: {{price}}
  {{#features}}
  Feature: {{description}}
  {{/features}}
{{/items}}

実行結果も同じ。

Name: Item 1
Price: $19.99
  Feature: New!
  Feature: Awesome!
Name: Item 2
Price: $29.99
  Feature: Old.
  Feature: Ugly.

Javaの様にクラスを使ってもいいのですが、簡単に使いたい時はGroovyのリテラル表記が便利ですね。

一応、build.gradleを含めて全部載せておきます。
build.gradle

apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'application'

version = '0.0.1-SNAPSHOT'

mainClassName = 'example.mustacheg.MustacheExample'

repositories {
    mavenCentral()
}

dependencies {
    compile 'com.github.spullara.mustache.java:compiler:0.8.8'
    groovy 'org.codehaus.groovy:groovy:2.0.5'
}

src/main/groovy/example/mustacheg/MustacheExample.groovy

package example.mustacheg

import com.github.mustachejava.DefaultMustacheFactory

class MustacheExample {
  static void main(String[] args) {
    def mf = new DefaultMustacheFactory()
    def mustache = mf.compile("template/simple-template.mustache")
    mustache.execute(new PrintWriter(System.out), createContext()).flush()
  }

  static def createContext() {
    [items: [
            [name: 'Item 1', price: '$19.99', features: [
                    [description: 'New!'], [description: 'Awesome!']]],
            [name: 'Item 2', price: '$29.99', features: [
                    [description: 'Old.'], [description: 'Ugly.']]]
    ]]
  }
}

テンプレート
template/simple-template.mustache

{{#items}}
Name: {{name}}
Price: {{price}}
  {{#features}}
  Feature: {{description}}
  {{/features}}
{{/items}}

mustache.javaのサイトのサンプルとは、テンプレートの置き先が異なります。