renderSnakeとは

renderSnake」は、JavaプログラムでHTMLコードを生成するためのライブラリである。複雑な手続きを必要とせずに、単純メソッド呼び出しだけで直感的にタグを出力できることや、少ないメモリ使用量で軽量に動作するため様々なアプリケーションに組み込んで利用できることなどが大きな特徴。Webアプリケーション開発での利用も積極的にサポートしており、ServletやJSP、Spring MVC、Google Guiceなどとの連携にも対応している他、フォームからの入力処理を簡略化する機能などが用意されている。

renderSnakeはApache License Version 2.0にもとづいて公開されており、Google Codeに開設されたプロジェクトサイトよりダウンロードすることができる。本稿執筆時点における最新版はバージョン1.1。HTML5で追加された新しいタグや属性、Spring MVCやGoogle Guiceとの連携、静的リソースの読み込みやテンプレートの利用などがサポートされている。また、スナップショットの段階ながらjQueryも一部サポートしている。

renderSnakeでHTMLコードを出力する

ダウンロードしたファイルを解凍すると、jarsフォルダに本体となるjarファイルが格納されている。jQueryを使わない場合は、「rendersnake-1.1.jar」をクラスパスに含めて利用すればよい。その他、別途Apache Commons Langをダウンロードしてクラスパスに含めておくとよい(後述するwtite()メソッドがCommons Langのテキストエスケープ機能を利用するため)

renderSnakeによるHTMLコード生成の基本となるのがHtmlCanvasクラスである。このクラスにはHTMLのタグを出力するためのメソッドが、それぞれのタグごとに用意されている。例えばHTMLタグに対応したhtml()や、bodyタグに対応したbody()などだ。閉じタグはメソッド名の先頭にアンダースコアがついた_html()、_body()のようになっている。

HtmlCanvasのインスタンスは、コードの出力先となるWriterオブジェクトを指定して次のように生成する。

FileWriter writer = ...;
HtmlCanvas html = new HtmlCanvas(writer);

このHtmlCanvasオブジェクトに対して、次のようにbody()メソッドを呼び出したとする。

html.body();

すると指定されたWriterを経由して次のHTMLコードが出力される。

<body>

さて、html()やbody()などのタグ出力用メソッドは、戻り値として現在使用中のHtmlCanvasオブジェクトそのものを返すようになっている。したがって、次のようにメソッドを連続で呼び出すことで複数のタグの出力を1行で書くことができる。

html.html().body()._body()._html();

この結果は次のようになる。

<html><body></body></html>

以下のコードは、「output1.html」にHTMLコードを出力するプログラムの例である。

package jp.co.mycom.toolde.rendersnake;


import java.io.*;
import org.rendersnake.HtmlCanvas;


public class CreateHtml1 {
  public static void main(String[] args) {
    CreateHtml1 doit = new CreateHtml1();
  }

  public CreateHtml1() {
    FileWriter writer = null;
    try {
      // 出力先を指定してHtmlCanvasを生成
      writer = new FileWriter("output1.html");
      HtmlCanvas html = new HtmlCanvas(writer);

      // HTMLコードを出力
      html.html()
          .body()
            .h1()
              .write("renderSnakeのサンプル")
            ._h1()
          ._body()
        ._html();


    } catch (IOException ex) {
      ex.printStackTrace();
    } finally {
      try {
        writer.close();
      } catch (IOException ex) {
        ex.printStackTrace();
      }
    }
  }
}

h1()はh1タグを、write()はプレーンテキストを出力するためのメソッドである。write()の第一引数には出力するテキストを渡す。このプログラムによって出力されたHTMLコードは次のようになった。Webブラウザで表示すると図1のようになる。

<html><body><h1>renderSnakeのサンプル</h1></body></html>

図1 : renderSnakeを利用して生成したHTMLの例

なお、HtmlCanvasのコンストラクタを引数なしで呼び出した場合、出力先は自動的に内部的なStringWriterオブジェクトとなる。このStringWriterに出力された内容は、toHtml()メソッドを呼び出すことでStringとして取り出すことができるようになっている。

タグに属性を付ける

続いて、出力するタグに属性を付けてみよう。属性を出力するにはHtmlAttributesクラスを利用する。このクラスのインスタンスは、属性の名前と値をセットにして保持する。これをタグ出力用のメソッドに渡すことで、指定された属性が付けられたタグが出力される。例えばbodyタグにonload属性を付けたい場合は次のように記述すればよい。

html.body(new HtmlAttributes("onload", "init()"));

出力結果は次のようになる。

<body onload="init()">

HtmlAttributesには、add()メソッドを使って複数のタグを追加することもできる。また、属性名に対応したメソッドが用意されており、このメソッドの引数に値を渡して呼び出すことで属性を追加することもできるようになっている。これらのメソッドはHtmlAttributesオブジェクト自身を返すため、HtmlCanvasの場合と同様に連続して呼び出すことが可能。例えば以下のような感じだ。

HtmlAttributes attr = new HtmlAttributes("id", "hoge");
attr.add("class", "piyo");
attr.width("100").height("20");
html.div(attr);

出力結果は次のようになる。

<div id="hoge" class="piyo" width="100" height="20">

一般的に利用する属性についてはHtmlAttributesFactoryクラスを利用すると便利だ。このクラスには各属性に対応したstaticメソッドが用意されており、引数として値を指定して呼び出すことで対応するHtmlAttributesオブジェクトを生成してくれる。このクラスを利用すると、上のdivタグの例は次のように記述できる。

html.div(HtmlAttributesFactory.id("hoge").class("piyo").width("100").height("20"));

この方法を用いて入力フォームを生成するコードを生成してみよう。この場合、formタグやinputタグに属性を付ける必要がある。以下にHTML出力部分の例を示す。

html.html()
  .body(new HtmlAttributes("onload", "init()"))
    .h1()
      .write("renderSnakeのサンプル")
    ._h1()
    .form(HtmlAttributesFactory.action("/FormAction").method("POST"))
      .label(HtmlAttributesFactory.for_("message"))
        .write("メッセージ:")
      ._label()
      .input(HtmlAttributesFactory.type("text").id("message"))
      .input(HtmlAttributesFactory.type("submit").value("送信"))
    ._form()
  ._body()
._html();

出力結果は以下のようになる(見やすいように改行を入れている)。Webブラウザでの表示は図2のようになる。

<html>
  <body onload="init()">
    <h1>renderSnakeのサンプル</h1>
    <form action="/FormAction" method="POST">
      <label for="message">メッセージ:</label>
      <input type="text" id="message"/>
      <input type="submit" value="送信"/>
    </form>
  </body>
</html>

図2 :タグに属性を追加した例

Renderableでコード生成をコンポーネント化する

HTML生成部分の細分化や、何度も使うコードの再利用にはRenderableインタフェースによるコンポーネント化を利用しよう。このインタフェースにはHtmlCanvasオブジェクトを受け取るrenderOn()というメソッドが定義されている。これをオーバーライドし、渡されたにHtmlCanvasに対してタグを出力するコードを追加してみる。次に示すMyFormComponentクラスは、前述のフォームの例から入力フォームを生成する部分だけを抜き出し、それをrenderOn()の処理とした例である。

public class MyFormComponent implements Renderable {
  @Override
  public void renderOn(HtmlCanvas html) throws IOException {
    // フォーム用のコードを出力
    html.form(HtmlAttributesFactory.action("/FormAction").method("POST"))
      .label(HtmlAttributesFactory.for_("message"))
        .write("メッセージ:")
      ._label()
      .input(HtmlAttributesFactory.type("text").id("message"))
      .input(HtmlAttributesFactory.type("submit").value("送信"))
    ._form();
  }
}

HtmlCanvasクラスにはrender()というメソッドが用意されている。このメソッドにRenderableをimplementsしたクラスのインスタンスを渡すと、、呼び出し元のHtmlCanvasインスタンスを引数としてrenderOn()が実行される。したがって、以下のようにMyFromComponentを利用するれば、先ほどの入力フォームの例と同様のHTMLコードが出力されるということだ。

html.html()
  .body(new HtmlAttributes("onload", "init()"))
    .h1()
      .write("renderSnakeのサンプル")
    ._h1()
    .render(new MyFormComponent())
  ._body()
._html();

次回は、renderSnakeのサーバサイドでの利用方法を紹介しよう。