本格派エンジニアの工具箱

第10回Apache Clickにおけるテンプレートとコントロールの使い

テンプレートを利用する

今回は、前回紹介した軽量WebアプリケーションフレームワークApache Clickにおいて、テンプレートやコントロールを利用する方法を解説します。まずはテンプレートからやっていきましょう。

Apahe ClickではApache Velocityによるテンプレート・エンジンを利用しています。これによって、Webサイト内の複数のページの共通部分をテンプレート化して簡単に見た目を整えることができるようになっています。テンプレートの作り方ですが、まずベースとなるhtmlファイルを作成します。ここでは次のような内容で、ファイル名を「my-template.htm」としました。

<html>
  <head>
    <title>Apache Click Sample - $title</title>
  </head>
  <body>

    <div id="header" style="background-color: #333333">
      <h1 style="color: white">$title</h1>
    </div>
    
    <div id="contents" style="padding: 1em 0.5em 1.5em">
      #parse($path)
    </div>

    <hr style="color: #333333" />
    <div align="right" style="color: #666666">$copyright</div>

  </body>
</html>

テンプレート内でも、通常のWebページと同様にサーバ上のJavaオブジェクトを利用することができます。この例では、$titleと$copylightが、関連付けられたJavaオブジェクトの値に置き換わる部分です。ページごとのコンテンツは「#parse($path)」と書いた部分に挿入されます。#parseはVelocityテンプレートエンジンを用いてパースされたテンプレートを描画するためのメソッドです。$pathはテンプレートファイルのパスで、ClickServletによって自動的に値がセットされます。

my-template.htmに関連付けるサーバ側のJavaクラスは、自動マッピングの規則にしたがって「MyTemplate」という名前にします。このクラスは、通常のWebページ用のクラスと同様にPageクラスを継承して作成し、以下のようにgetTemplate()メソッドをオーバーライドして対象となるテンプレート用ファイルを返すようにします。

MyTemplate.java
package jp.gihyo.toolbox.click;

import org.apache.click.Page;

public class MyTemplate extends Page {
  @Override
  public String getTemplate() {
    return "/my-template.htm";
  }
}

続いて、このテンプレートを適用するWebページを作成します。まずJavaプログラムの方はMyTemplateクラスを継承して作成します。ここで、次に示すようにテンプレート内で使用されているtitleとcopyrightの変数を宣言しておきます。

SecondPage.java
package jp.gihyo.toolbox.click;

public class SecondPage extends MyTemplate {
  public String title = "テンプレートの使用";
  public String copyright = "(C) 2011 杉山貴章";
}

クラス名が「SecondPage」なので、これに対応するhtmlは「second-page.htm」とします。内容は、テンプレートの「#parse($path)」の部分に挿入したい内容で、ここではシンプルに次のようにしました。

<p>Apache Clickでテンプレートを使用した例です。</p>

できたら、サーバに配備してWebブラウザからsecond-page.htmにアクセスすると、図1のようにテンプレートが適用されたページが表示されるはずです。

図1 テンプレートが適用されたWebページ
図1 テンプレートが適用されたWebページ

コントロールを使用して入力値を渡す

続いて、コントロールを利用してWebブラウザからサーバ側のプログラムに値を渡す方法を解説します。例として、ログインフォームを表示し、ユーザ名とパスワードを入力してボタンを押すと次のページへ飛ぶようなページを考えます。まず、ログイン用ページのJava側のプログラムは次のような具合になります。

LoginPage.java
package jp.gihyo.toolbox.click;

import org.apache.click.control.Form;

public class LoginPage extends MyTemplate {
  // テンプレート用
  public String title = "ログイン";
  public String copyright = "(C) 2011 杉山貴章";
  
  // 入力フォーム
  public Form loginForm = new Form();
  
  private TextField nameField = new TextField("username", "ユーザ名", true);

  public LoginPage() {
    // 入力フォームを構成
    this.loginForm.add(this.nameField);
    this.loginForm.add(new PasswordField("password", "パスワード", true));
    this.loginForm.add(new Submit("login", "ログイン", this, "onLoginClick"));
    
    addModel("loginform", this.loginForm);
  }

  public boolean onLoginClick() {
    if (loginForm.isValid()) {
      // ......ログイン認証処理......

      // welcome-page.htmへユーザ名を渡す
      WelcomePage welcomePage = (WelcomePage)getContext().createPage("/welcome-page.htm");
      welcomePage.setUsername(this.nameField.getValue());
      setForward(welcomePage);
    }
    return true;
  }
}

Apache Clickには、WebページのUIと、サーバ上のJavaオブジェクトをつなぐためのコントロール用のクラスが用意されています(詳細はAPIドキュメント参照⁠⁠。これらは概ねHTMLに用意されたテキストフィールドやボタンなどのUIパーツに対応するもので、全てがorg.apache.click.control.Controlインタフェースの実装クラスになっています。本稿の例では、まずフォームを構成するためのFormオブジェクトを生成し、そこにテキストフィールドのためのTextField、パスワード入力フィールドのためのPasswordField、SubmitボタンのためのSubmitの各オブジェクトをadd()メソッドを用いて追加しています。

TextFieldとPasswordFieldでは、コンストラクタの第2引数に渡した文字列がキャプションになります。また第3引数にtrueを渡すことで、そのフィールドへの入力を必須にすることができます。Submitクラスのコンストラクタでは、第2引数にボタンのラベル、第3引数にボタンが押された場合のリスナとなるクラスのオブジェクト、第4引数に実際に呼ばれるメソッドの名前を渡します。つまり、この例ではボタンが押されるとLoginPageクラス自身のonLoginClick()メソッドが実行されるということです。

onLoginClick()メソッドでは、WelcomePageクラス(後述)のインスタンスを生成し、そこにnameFieldに入力された値をセットするという処理を行っています。簡略化のため今回はログイン認証処理は省略します。

LoginPageクラスに対応するhtmlファイルは、login-page.htmという名前で作成し、内容は以下のようにしました。

<p>ユーザ名とパスワードを入力してログインしてください。</p>

$loginform

$loginformは、LoginPageのFormオブジェクトに対応しています。

最後に、[ログイン]ボタンを押した後に表示するページを作成します。Javaクラスは先述のWelcomePageで、内容は以下のようにな感じなります。

WelcomePage.java
package jp.gihyo.toolbox.click;

public class WelcomePage extends MyTemplate {
  // テンプレート用
  public String title = "ようこそ";
  public String copyright = "(C) 2011 杉山貴章";
  
  // ユーザ名
  private String username;
    
  @Override
  public void onInit() {
    super.onInit();
    if (this.username != null) {
      addModel("username", this.username);
    }
  }
    
  public void setUsername(String username) {
    this.username = username;
  }
}

onInit()はPageインスタンスの初期化のために実行されるメソッドです。WelcomePageではこれをオーバーライドして、usernameプロパティの値にWebページの$username変数でアクセスできるように設定しています。usernameプロパティは、LoginPageクラスによってフォームから入力されたユーザ名がセットされているはずです。ただし、onInit()メソッドをオーバーライドする場合には、必ずスーパークラスのonInit()を明示的に呼ぶ必要があります。

WelcomePageに対応するhtmlファイルはwelcome-page.htmという名前で作成し、内容は$usernameを使って次のようにしました。

<p>ようこそ <strong>$username</strong> さん。</p>

完成したら、サーバに配備してlogin-page.htmにアクセスしてみましょう。最初に図2のようにフォームが表示されるので、適当なユーザ名とパスワードを入力して[ログイン]ボタンをクリックします。するとwelcome-page.htmに移動し、図3のように入力したユーザ名が反映されていることが確認できます。

図2 フォームにユーザ名とパスワードを入力する。⁠*」は入力が必須であることを示すマーク
図2 フォームにユーザ名とパスワードを入力する。「*」は入力が必須であることを示すマーク
図3 入力したユーザ名が反映されている
図3 入力したユーザ名が反映されている

このように、Apache Clickではサーバ側のプログラムは基礎的なJavaプログラム(POJO)として、Webページ側のUIはHTMLとして、独立して定義することができます。言い換えれば、JavaとHTMLの知識があれば、SercletやJSP(JavaServer Pages)などの仕組みは意識しなくてもアプリケーションが組めるということです。"軽量"という売り文句が示すように、Webアプリケーションを手早く開発するために便利なフレームワークです。

おすすめ記事

記事・ニュース一覧