テンプレート機能

今回はテンプレートについて書きます。

【前提条件】

[環境]

【内容】

テンプレートはベースとなるページに
別ページの内容を出力する機能です。

Struts1でいうところのtilesです。

まずはテンプレートとなるページです。
「layout.xhtml」としてコンテキストルートに配置します。

<?xml version="1.0" encoding="windows-31j" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"> 
    <h:head>
        <title>テンプレート</title>
    </h:head> 
    <h:body>
        <f:view>
            <div id="header" style="background-color : #FFDDDD">
                <ui:insert name="header"/>
            </div>
            <div id="content" style="background-color : #DDFFDD">
                <ui:insert name="content"/>
            </div>
            <div id="footer" style="background-color : #DDDDFF">
                <ui:insert name="footer"/>
            </div>
        </f:view>
    </h:body>
</html>

別ページをインクルードしたい箇所にタグを使用します。
タグにはname属性を設定します。
今回は「header」「content」「footer」の三つを用意します。

続いてテンプレートを使用する側です。
「content1.xhtml」と「content2.xhtml」として
コンテキストルートの下に作成します。

まずは「content1.xhtml」です。

<?xml version="1.0" encoding="Windows-31J" ?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    template="layout.xhtml">
    <ui:define name="header">
        コンテンツ1のheader部です。
    </ui:define>
    <ui:define name="content">
        コンテンツ1のcontent部です。
    </ui:define>
    <ui:define name="footer">
        コンテンツ1のfooter部です。
    </ui:define>
</ui:composition>

つづいて「content2.xhtml」です。

<?xml version="1.0" encoding="Windows-31J" ?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    template="layout.xhtml">
    <ui:define name="header">
        コンテンツ2のheader部です。
    </ui:define>
    <ui:define name="content">
        コンテンツ2のcontent部です。
    </ui:define>
    <ui:define name="footer">
        コンテンツ2のfooter部です。
    </ui:define>
</ui:composition>

テンプレートを利用するページはタグで囲います。
template属性に先ほど作成した「layout.xhtml」を指定します。

タグに表示したい内容を書きます。
name属性にはインクルードしたい箇所の名称を指定します。
タグとタグでname属性の値が一致する箇所にインクルードされます。

「content1.xhtml」にアクセスしてみます。

「content2.xhtml」にアクセスしてみます。

どちらも「layout.xhtml」のスタイルが適用されています。

ヘッダー・フッターというと基本的に多くの画面で共通的なものを使用すると思います。
name属性が「header」「footer」だけ、共通のものを使用し、
「content」部分だけ個別のページを適用する方式に変えてみます。

共通のヘッダーとフッターを用意し、コンテキストルートの下に作成します。
それぞれ、「header.xhtml」と「footer.xhtml」とします。

まずは「header.xhtml」です。

<?xml version="1.0" encoding="Windows-31J" ?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets">
    共通のヘッダーです
</ui:composition>

続いて「footer.xhtml」です。

<?xml version="1.0" encoding="Windows-31J" ?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets">
    共通のフッターです
</ui:composition>

今度はテンプレートのページ側を修正します。
「layout.xhtml」を↓のように書き換えます。

<?xml version="1.0" encoding="windows-31j" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"> 
    <h:head>
        <title>テンプレート</title>
    </h:head> 
    <h:body>
        <f:view>
            <div id="header" style="background-color : #FFDDDD">
                <ui:insert name="header">
                    <ui:include src="/header.xhtml" />
                </ui:insert>
            </div>
            <div id="content" style="background-color : #DDFFDD">
                <ui:insert name="content"/>
            </div>
            <div id="footer" style="background-color : #DDDDFF">
                <ui:insert name="footer">
                    <ui:include src="/footer.xhtml" />
                </ui:insert>
            </div>
        </f:view>
    </h:body>
</html>

ヘッダーとフッターのタグの子要素に
タグを追加しただけです。

タグのsrc属性には
インクルードしたいページを指定します。

では、新たに「content」部分のページを作成します。
それぞれ「content3.xhtml」「content4.xhtml」を
コンテキストルートの下に作成します。

まずは「content3.xhtml」です。

<?xml version="1.0" encoding="Windows-31J" ?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    template="layout.xhtml">
    <ui:define name="content">
        コンテンツ3のcontent部です。
    </ui:define>
</ui:composition>

つづいて「content4.xhtml」です。

<?xml version="1.0" encoding="Windows-31J" ?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    template="layout.xhtml">
    <ui:define name="content">
        コンテンツ4のcontent部です。
    </ui:define>
</ui:composition>

「content3.xhtml」にアクセスしてみます。

「content4.xhtml」にアクセスしてみます。

「content3.xhtml」「content4.xhtml」ともに
ヘッダー・フッターは共通のものが表示されます。

同じ「layout.xhtml」を使用している、
「content1.xhtml」「content2.xhtml」にアクセスします。

変更前と変わらない結果となります。
これは「content1.xhtml」「cotent2.xhtml」が
ヘッダー・フッターを上書きしているからです。

JSF2.0のインクルードは
Sturts1よりはるかに簡単に設定ができます。

次回はインクルードの入れ子について書きます。