カスタム Utility Object を追加する ー Thymeleaf

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

全国5,000人ほどのThymeleafファンの皆様、こんにちは。AWSチームのフロントエンド担当の渡辺です。

Thymeleafは、Springフレームワークのテンプレートエンジンとして利用されるケースが多いXHTMLベースのテンプレートエンジンです。日本語の情報はあまりヒットしませんので、拡張方法など小ネタを放出したいと思います。

Utility Objectとは?

Thymeleafではオブジェクトの値を次のように宣言してレンダリングします。

<span th:text="${person.name}">Shuji</span>

これで、personオブジェクトのnameプロパティがレンダリングされるので非常に直感的で、かつテンプレートの属性がHTML(モック)を汚染しないのが特徴です。したがって、モックからテンプレートへの変換が容易ですし、テンプレート化した後もモックとして表示できます。

Utility Objectとは、Thymeleafの拡張書式です。デフォルトで幾つかのオブジェクトが定義されており、次のようにするとname属性の文字数をカウントして表示します。

<span th:text="${#strings.length(person.name)}">Shuji</span>

Rails系の言い方をすれば、Helperオブジェクトですね。

他にも様々なUtility Objectが提供されていますが、独自で追加するには少々面倒な感じです。

カスタムUtility Objectの登録

カスタム Utility Objectを登録するにはDialectを作成する必要があります。Dialectとは方言で、アプリケーション特有の拡張をThymeleafに設定する機能です。カスタムUtility Objectを登録するには、IExpressionEnhancingDialectインターフェイスを実装したDialectを作成し、getAdditionalExpressionObjectsメソッドをオーバーライドします。

public class MyUtility() {
  public String hello(String text) { return "Hello, " + text; }
}
public class MyDialect extends AbstractDialect implements IExpressionEnhancingDialect {
  private static final Map<String, Object> EXPRESSION_OBJECTS;
  static {
    Map<String, Object> objects = new HashMap<>();
    objects.put("helper", new MyUtility());
    EXPRESSION_OBJECTS = Collections.unmodifiableMap(objects);
  }
  @Override
  public Map<String, Object> getAdditionalExpressionObjects(IProcessingContext processingContext) {
    return EXPRESSION_OBJECTS;
  }
  // 他の実装は省略  
}

これで、helperがカスタムUtility Objectとして追加されるので、次のような形でヘルパーを使うことができます。

<span th:text="${#helper.hello(person.name)}">Shuji</span>