[Subsonic Airlines] Faceletsの使用

今回は、Faceletsについて説明します。

Faceletsは、JSFのテンプレート機能を提供します。

開発環境
Windows 7 64ビット
Eclipse Luna 4.4.2 64ビット
JBoss Tools 4.2.3.Final
PrimeFaces 5.2
WildFly 8.2.0.Final

ソースコードはGitHubに置きました。
https://github.com/subsonicsystems/subsonic-airlines-facelets

プロジェクトの作成
プロジェクト名をsubsonic-airlines-faceletsとしています。

subsonic-airlines-facelets.war
warファイルは、次の通りです。
1

設定ファイル
web.xmlは、次の通りです。
/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1"
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    <context-param>
        <param-name>primefaces.THEME</param-name>
        <param-value>bootstrap</param-value>
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

/WEB-INF/faces-config.xml
JSF2.2では、faces-config.xmlはオプションとなりました。今回は、faces-config.xmlはありません。

リソース
/resources/css/default.css
/resources/images/header.png

CSSファイルや画像ファイルは、規約により次のディレクトリに配置します。
/resources/[locale-prefix/][library-name/][library-version/]resource-name[/resource-version]

[ ]は、オプションです。

今回の例では、library-nameをcssとimagesにしています。library-nameは、任意の名称を付けることができますので、この通りでなくても構いません。

xhtmlファイル
/template.xhtml

<!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:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:p="http://primefaces.org/ui">
    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <h:outputStylesheet library="css" name="default.css"/>
        <title>Subsonic Airlines</title>
    </h:head>
    <h:body>
        <div>
            <p:graphicImage library="images" name="header.png" styleClass="header"/>
        </div>
        <div>
            <ui:insert name="content"/>
        </div>
        <div class="height300"></div>
        <div>
            &#169; 2015 Subsonic Airlines
        </div>
    </h:body>
</html>

template.xhtmlは、テンプレートファイルです。ファイル名は、template.xhtmlでなくても構いません。

テンプレートファイルは、別のxhtmlファイルによって参照されます。

htmlタグのxmlns:uiは、Faceletsの宣言です。xmlns:pは、PrimeFacesの宣言です。

h:outputStylesheetタグは、CSSファイルの場所を指定しています。CSSファイルが/resources/css/default.cssの場合、library=”css” name=”default.css”となります。

p:graphicImageタグは、imgタグを生成します。画像ファイルが/resources/images/header.pngの場合、library=”images” name=”header.png”となります。

ui:insertタグは、挿入される場所を指定するために使います。テンプレートファイルを呼び出すxhtmlファイルのui:defineタグと対応しています。同じname属性のui:insertタグとui:defineタグが対となります。

今回の例では、index.xhtmlの<ui:define name=”content”>とtemplate.xhtmlの<ui:insert name=”content”/>が対応しています。

/index.xhtml

<!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:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
    <h:body>
        <ui:composition template="./template.xhtml">
            <ui:define name="content">
                <h:outputText value="Subsonic Airlinesへようこそ"/>
            </ui:define>
        </ui:composition>
    </h:body>
</html>

index.xhtmlは、テンプレートファイルを呼び出す側のファイルです。

ui:compositionタグは、呼び出すテンプレートファイルを指定します。

ui:defineタグは、テンプレートファイルのui:insertタグに挿入する内容を定義します。index.xhtmlの<ui:define name=”content”>と</ui:define>に囲まれている部分が、template.xhtmlの<ui:insert name=”content”/>を置き換えます。

整理すると、次のようになります。

1 index.xhtmlが呼び出されます。
2 index.xhtmlは、ui:compositionタグのtemplate属性に./template.xhtmlを指定しているので、template.xhtmlがテンプレートとして使用されます。
3 template.xhtmlの<ui:insert name=”content”/>がindex.xhtmlの<ui:define name=”content”>と</ui:define>に囲まれている部分に置き換えられます。
4 template.xhtmlが応答内容として出力されます。

すなわち、index.xhtmlを呼び出して出力される内容は、index.xhtmlが元となるのではなく、template.xhtmlにindex.xhtmlのui:defineを合成した内容となります。

そして、index.xhtmlの<ui:define name=”content”>と</ui:define>に囲まれていない部分については、出力されません。

デプロイ
デプロイに成功すると、次の通り表示されます。

http://localhost:8080/subsonic-airlines-facelets/
2