Closure Templatesことはじめ - Java編

# Closure Templatesって？

Closure Templatesとは、Googleが開発しているJavaとJavaScriptで利用可能なテンプレートエンジンです。
GmailやGoogle Docsで利用されている（されていた？）という実績もあり、最近では[Medium](https://medium.com/)というサービスでも利用されています。

個人的に気に入っている点をあげてみます。

- JavaとJavaScriptで同じテンプレートファイルを利用できるので、初期ページはサーバーサイドのJavaで描画し、動的に書き換えたい箇所だけクライアントサイドのJavaScriptで描画し直すようなことが簡単に実現できる。
- オートエスケープやパラメータの型チェックなど、安全にテンプレートを書くための機能が充実している。
- テンプレート内でできることが限られているので、メンテナンス性の低い複雑な実装になりにくい。
- VelocityやFreemarkerと同程度の描画パフォーマンス。

特に尖った機能があるわけではありませんが、バランスが取れていて使いやすいテンプレートエンジンだと思います。

さて、まず今回はJavaでのClosure Templatesの利用方法を紹介します。

# Closure Templatesのインストール

さっそくClosure Toolsのサイトからダウンロードしましょう。

- https://developers.google.com/closure/templates/

と言いたいところなんですが、公式サイトからダウンロードできるファイルは2012年にリリースされた古いバージョンのものです。（最新版は2014年4月にリリースされています）
Mavenのリポジトリにも登録されていません。
なんというやる気のなさ。


最新版の機能を利用したいので、ここではリポジトリからソースコードを持ってきてビルドすることにします。

## Closure Templatesのビルド

まずはGitHubからソースコードを落としてきます。
Closure Templatesは、以前はGoogle Codeで管理されていたのですが、現在はGitHubに移行しています。

~~~
$ git clone https://github.com/google/closure-templates.git
$ cd closure-templates
~~~

masterのものが安定版かどうかも分からないので、リリース版を使いたいのであれば以下のリビジョンに切り替えます。（リリースタグはありません…）

~~~
$ git checkout 8ece726
~~~

ビルドをおこなうためには、事前にJava 7とAntをインストールしておきます。
そしてAntコマンドを実行してビルドします。

~~~
$ ant jar
~~~

ビルドに成功するとbuildディレクトリの下にsoy.jarができているので、これをコピーして利用しましょう。

# サンプルプログラムを動かしてみる

## Vert.xのインストール

JavaでWebアプリケーションをつくろうと思うと、たくさんのJavaファイルと複雑なXMLの設定ファイルを書いて、Mavenでビルドして…と、面倒くさそうなイメージがあります。
ですが、さくっとWebアプリをつくることのできるフレームワークも数多く存在します。
そんな中でも、今回はVert.xを使ってみたいと思います。

- http://vertx.io/

Vert.xは、Node.jsのようなノンブロッキングAPIや、Actorのような並列実行の仕組みを持ったアプリケーションプラットフォームです。
Java, JavaScript(Rhino, Nashorn), Scala, Ruby(JRuby), Python(Jython), Groovy, ClojureなどJVM上で動く様々なプログラミング言語に対応しています。
詳細についてはここでは解説しませんが、興味を持った方は以下の記事がとても分かりやすいのでおすすめです。

- [Vert.x がいいね！（第1回：入門する）](http://acro-engineer.hatenablog.com/entry/2013/08/10/131203)

Vert.xを利用するためには、[ダウンロードページ](http://vertx.io/downloads.html)からファイルをダウンロードし、展開したディレクトリ内のbinにパスを通しておきます。

## サンプルプログラム

まずはテンプレートファイルを用意します。Closure Templatesのテンプレートファイルの拡張子は`.soy`になります。
パラメータにnameを渡して、挨拶を表示するだけの簡単なものです。

~~~soy:hello.soy
{namespace example.templates}

/**
 * @param name
 */
{template .hello}
  Hello, {$name}!
{/template}
~~~

続いてJavaのコードを用意します。
Webアプリケーションとして動作するための処理は、Node.jsっぽくてとてもシンプルですね。
Closure Templatesのためのコードは、テンプレートファイルを読み込んでコンパイルする処理と、テンプレートに渡すデータを用意してレンダリングする処理を書きます。

~~~java:HelloSoyVerticle.java
import com.google.template.soy.SoyFileSet;
import com.google.template.soy.data.SoyMapData;
import com.google.template.soy.tofu.SoyTofu;
import org.vertx.java.platform.Verticle;

import java.io.File;

public class HelloSoyVerticle extends Verticle {

  public void start() {
    // テンプレートファイルを読み込んでコンパイル
    SoyTofu tofu = SoyFileSet.builder()
        .add(new File("hello.soy"))
        .build()
        .compileToTofu();

    // GETリクエストがきたらレンダリングをして返す
    vertx.createHttpServer().requestHandler(req -> {

      // テンプレートに渡すデータを用意
      SoyMapData data = new SoyMapData("name", "World");

      // テンプレートにデータをセットしてレンダリング
      String output = tofu.newRenderer("example.templates.hello")
          .setData(data)
          .render();
      req.response().end(output);
    }).listen(8080);
  }
}
~~~

なお、サンプルプログラムはGitHubにもアップしてあります。

- https://github.com/zoetrope/closure-sandbox/tree/master/java_sample

## サンプルプログラムの実行

では、さっそく実行してみましょう。
上記のサンプルプログラムはラムダ式を利用しているので、アプリケーションの実行時にはJava 8を利用する必要があります。Closure Templatesのビルドの際にはJava 7を使ったので注意してください。

`HelloSoyVerticle.java`と`hello.soy`と`soy.jar`を同じディレクトリに置いて、次のコマンドでアプリケーションを起動します。

~~~
$ vertx run HelloSoyVerticle.java -cp soy.jar
~~~

Vert.xでは、Javaのソースファイルをコンパイルしなくても、そのまま引数に指定して実行することができるのでとても便利ですね。（もちろん事前にコンパイルすることも可能です）

ブラウザで`http://localhost:8080/`にアクセスして、`Hello, World!`と表示されたら成功です。