Mayaa for GAE/J でサイトのレイアウト共有機能を試してみた

Mayaa とは

はてなキーワードによると

Mayaa とは HTML をベースとしたテンプレートによるプログラマとデザイナの作業分担を強く意識したWEBフロントサービスエンジンです。オープンソースにて、Seasar ファウンデーションで開発されています。

と説明されてます。

Mayaa の機能については本家サイトに分かりやすいチュートリアルがあります。Teeda 同様にプレーンな HTMLをテンプレートにできるところが特徴的です。

Mayaa の機能の1つであるレイアウト共有機能を試したところ、プログラムの知識は一切必要とせず XML の設定のみで簡単に使用することができました。

ちなみにここで言うレイアウト共有機能とは、

「ページ個別のコンテンツ部分のみを記述したHTMLをページ数分用意、ヘッダやフッタといったレイアウトのみを記述したHTMLを用意、それらをウェブサーバ上に配置しておき、個別のページにアクセスが発生したタイミングで、レイアウトHTMLにそのページのコンテンツ部を埋め込んだHTMLをブラウザに返す機能」

の事を指しています。
以下に使用手順をまとめました。

開発環境とMayaaの準備

開発環境の準備

前回のエントリ「GAE/j (Google App Engine for Java) を活用するための Eclipse 環境の整備」の内容に従い準備します。尚 Mayaa しか使用しないのであれば必須となるプラグインは下記のもののみとなります。

あと必須ではありませんが、Mayaa用のプラグインとして matatabi とういうのがあり、Mayaa の設定ファイルを編集する際コード補完機能等を提供してくれます。(インストール方法は前回の記事に追記しました。)

Mayaa の準備

下記リポジトリより Mayaa のソースを取得します。手順については前回記事を参照。

GAEのアプリケーション作成アイコンをクリックして、ブランクプロジェクトを作ります。(Use GoogleWeb Toolkit のチェックははずします。)



リポジトリより取得した /mayaa-getting-start-gae/war/WEB-INF の直下のファイル・フォルダ全てをブランクプロジェクトの同フォルダ以下に上書きコピーします。(エクスプローラ上で行う)


レイアウト共有機能を使ってみる

Mayaa の基本構成

Mayaaでは基本的に、1つのHTMLファイル(テンプレートファイル)とそれに対応するmayaaファイル(設定ファイル)を用意することになります。mayaaファイルでは「フォームから受け取った値、DBから取得した値などをHTMLファイルのこの部分に出力する」といった処理系の記述をすることができます。

今回はレイアウト共有機能を使うので、mayaaファイルには「このHTMLファイル(テンプレートファイル)にはこのレイアウトファイル(HTML)を適用する」という指定を記述します。ちなみにレイアウトファイルもHTML形式で記述されこれに対するmayaaファイルも必要になります。

こうしてみるとレイアウトを共有するだけなのに個別ページが増える度、対となる mayaa ファイルも増えるのは煩雑に感じます。デフォルトレイアウト共有機能を使用すると個別ページの mayaa ファイルを1つにまとめることができます。


レイアウト共有機能を試す

下記 HTML ファイルと Mayaa ファイルを作成し /プロジェクト名/war/の直下に配置します。

layout.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <style>
            html{
                background:#333;
            }
            #header,
            #footer{
                background:#555;
                overflow:hidden;
                zoom:1;
                padding:16px;
            }
            #page-contents{
                background:#fff;
                padding:0 16px 128px;
            }
            h2{
                margin:0 -16px;
                padding:16px;
                background:#a0a0a0;
            }
        </style>        
    </head>
    <body>
        <div id="header">
            <h1>Site Name</h1>
        </div>
        <div id="page-contents">this is contents</div>
        <div id="footer">
            <address>address</address>
        </div>
    </body>
</html>

index.html

<html>
    <body id="page-contents">
        <h2>index.html</h2>
        <ol>
            <li>index.html</li>
            <li><a href="other.html">other.html</a></li>
        </ol>
    </body>
</html>

other.html

<html>
    <body id="page-contents">
        <h2>other.html</h2>
        <ol>
            <li><a href="index.html">index.html</a></li>
            <li>other.html</li>
        </ol>
    </body>
</html>

layout.mayaa

<?xml version="1.0" encoding="UTF-8"?>
<m:mayaa xmlns:m="http://mayaa.seasar.org">
    <m:insert id="page-contents" name="page-contents" replace="false"/>
</m:mayaa>

index.mayaa、other.mayaa

<?xml version="1.0" encoding="UTF-8"?>
<m:mayaa xmlns:m="http://mayaa.seasar.org" extends="/layout.html">
    <m:doRender id="page-contents" name="page-contents" />
</m:mayaa>

「プロジェクト名」右クリック→「実行」→「Web Application」でウェブサーバを起動、ブラウザを起動し以下URLにアクセスします。

レイアウトが共有されてることが確認できます。



デフォルトレイアウト共有機能を試す

先程作成した html、mayaa ファイルを以下のようにリネーム・削除します。

  • layout.html → defaultlayout.html
  • layout.mayaa → defaultlayout.mayaa
  • index.mayaa → default.mayaa
  • other.mayaa → 削除

下記設定ファイルを作成し/プロジェクト名/src/META-INF/の直下に配置します。(Eclipse 上で行う)

org.seasar.mayaa.provider.ServiceProvider

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE provider
    PUBLIC "-//The Seasar Foundation//DTD Mayaa Provider 1.0//EN"
    "http://mayaa.seasar.org/dtd/mayaa-provider_1_0.dtd">
<provider>
    <templateBuilder class="org.seasar.mayaa.impl.builder.DefaultLayoutTemplateBuilder">
        <resolver class="org.seasar.mayaa.impl.builder.injection.MetaValuesSetter"/>
        <resolver class="org.seasar.mayaa.impl.builder.injection.ReplaceSetter"/>
        <resolver class="org.seasar.mayaa.impl.builder.injection.RenderedSetter"/>
        <resolver class="org.seasar.mayaa.impl.builder.injection.InsertSetter"/>
        <resolver class="org.seasar.mayaa.impl.builder.injection.InjectAttributeInjectionResolver"/>
        <resolver class="org.seasar.mayaa.impl.builder.injection.EqualsIDInjectionResolver">
            <parameter name="reportUnresolvedID" value="true"/>
            <parameter name="reportDuplicatedID" value="true"/>
            <parameter name="addAttribute" value="{http://www.w3.org/TR/html4}id"/>
            <parameter name="addAttribute" value="{http://www.w3.org/1999/xhtml}id"/>
        </resolver>
        <resolver class="org.seasar.mayaa.impl.builder.injection.XPathMatchesInjectionResolver"/>
        <parameter name="outputTemplateWhitespace" value="true"/>
        <parameter name="outputMayaaWhitespace" value="false"/>
        <parameter name="optimize" value="true"/>

        <parameter name="defaultLayoutPageName" value="/defaultlayout.html"/>
        <parameter name="generateMayaaNode" value="true"/>

    </templateBuilder>
</provider>

(公式サイトの説明では templateBuilder 要素の class 属性は org.seasar.mayaa.impl.builder.DefaultLayoutTemplateBuilderImpl を指定するとあったのですが、実行時にクラスなしのエラーになるので調べたところ Impl なしクラスがあったのでこちらを指定したらエラーが無くなりました。)

Eclipse を一旦終了し再度起動します。(単にウェブサーバの再起動をしたいだけなのですが方法が分かりません...><)
「プロジェクト名」右クリック→「実行」→「Web Application」でウェブサーバを起動、ブラウザを起動し以下URLにアクセスします。

レイアウト共有機能を使った場合と同様に表示されることが確認できます。

デフォルトレイアウトを適用したくない場合

デフォルトレイアウト共有機能を使ってる状態で、デフォルトレイアウトを適用したくないページがあった場合は、そのページ用の mayaa ファイルを作り extends 属性の値に何も指定しないとレイアウトが適用されなくなります。例えば other.html にデフォルトレイアウトを適用したくない場合は以下のようにします。

other.mayaa

<?xml version="1.0" encoding="UTF-8"?>
<m:mayaa xmlns:m="http://mayaa.seasar.org" extends="">
    <m:doRender id="page-contents" name="page-contents" />
</m:mayaa>

ちなみにデフォルトレイアウトと異なるレイアウトを適用したい場合は、その適用したいレイアウトファイルを extends 属性に指定すればOK・・・と公式サイトに書かれてたのですが何故かうまくいきませんでした。(値を指定すると必ずデフォルトレイアウトが適用されてしまう。)