-テンプレート自動選択機能

Hello Mayaサンプルでは、テンプレートがWEBページ毎に1枚のみでしたが、MayaはWEB1ページに複数のテンプレートを関連付けることができます。これは、たとえば以下のような要件を満たすためです。

  • ロケールによって英語が記述されたテンプレートと日本語が記述されたテンプレートを切り替える
  • 時間や曜日によって切り替える。夜になったら画面全体が暗くなったり、日曜日は画面全体が赤かったりなど
  • ログインユーザー属性で切り替える。ゴールドメンバーはゴールドになるとか、性別や年齢に応じて文言やデザインが変更されるなど
  • ランダムに切り替える。アクセスのたびにデザインが変更されているように見せるなど

WEBサイトの国際化(I18N)を行うとき、もちろんすでにJSTLタグやStrutsタグなど普通にI18N化されてますので、国際化アプリケーションはテンプレートの切り替え機能がなくとも作れるでしょうが、I18Nコンポーネントレベルで行うと、動的でないデザイン要素についてもすべてカスタムタグに置き換える必要があり、開発および実行に時間コストが発生します。そのときはいささか乱暴にも聞こえますが、HTMLテンプレートをコピーして、該当箇所を直に翻訳してしまうという方法があります。Mayaは複数のテンプレートのうち、ユーザーのリクエスト等の情報とMaya設定XMLの設定から適切なテンプレートを見つけ、切り替えてサービスします。

[list.6 /maya-page/locale.html]
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
  </head>
  <body>
    Your locale is default, so I provide by english.
  </body>
</html>

[list6]は単純にするために、カスタムタグのインジェクション等は行っていません。ただ英語で文言を書いたHTMLファイルです。

[list.7 /maya-page/locale_ja.html]
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=Shift_JIS">
  </head>
  <body>
    あなたのロケールは「ja」です。日本語で表示します。
  </body>
</html>

[list7]は[list6]をそのまま翻訳しただけです。文言が日本語のほか、metaタグによるエンコーディング指定がShift_JISになっています。

[list.3 /maya-page/locale.maya]
<?xml version="1.0" encoding=" ISO-8859-1"?>
<!DOCTYPE maya 
    PUBLIC "-//The Seasar Project//DTD Maya page specification 0.1//EN" 
    "http://www.seasar.org/dtd/maya_0_1.dtd">
<maya>
  <model name="localeModel" scope="application"
    class="sample.org.seasar.maya.hellomaya.localeModel"/>
  <page suffix="${ localeModel.processLocale(mayaContext) }">
    <template encoding="ISO-8859-1"/>
    <template suffix="ja" encoding="Shift_JIS"/>
  </page>
</maya>

テンプレート切り替え関連の設定についてはMaya設定XMLに記述します。どうしてもこれはHTMLテンプレートには書けません。なぜなら自分を探すルールを自分には書けないためです。テンプレートの切り替えは、pageエレメントおよびその子エレメントのtemplateエレメントによって設定します。
<page suffix="${ localeModel.processLocale(mayaContext) }" default="en">
テンプレートは、local.htmlとlocale_ja.htmlのように、名前 + _(アンダースコア) + 接尾辞 + 拡張子、という命名規則に準拠したファイルがMaya設定XMLと同じフォルダに配置されている必要があります。pageエレメントのsuffix属性は、その接尾辞を取得するためのバインディング情報設定です。localModelは同じXML中でmodelエレメントによって登録されていますが、サンプルソースコードは以下のとおりです。

package sample.org.seasar.maya.hellomaya;
import java.util.Locale;
import org.seasar.maya.MayaContext;
public class LocaleModel {
  public String processLocale(MayaContext context) {
    Locale locale = context.getHttpServletRequest().getLocale();
    return locale.getLanguage();
  }
}

suffix属性にバインディングした値にしたがって、locale [+ _ + バインディング値] + .htmlより、適切なテンプレートを探します。テンプレートを読み込むためのエンコーディングは、pageエレメントの子templateエレメントでsuffix属性が合致するものがあればそのencoding属性の値を利用します。pageエレメントのsuffix属性において得られた接尾辞値ではテンプレートが見つからない場合、接尾辞無しのテンプレートで決定します。それでも見つからない場合には、エンジンが実行時例外を送出し、サーブレットは404(ページが見つからない)をHTTPステータスコードとして返します。
サンプルでは、ロケールを接尾辞として、I18Nの簡単な例を示しましたが、接尾辞の設計において、morning / afternoon / evening / night として時間によってテンプレートを変えたり、girl / boy/ female / male としてユーザーの年齢や性別によってテンプレートを切り替えるなどが可能となります。