JSF2.2で「Big Ticket」と呼ばれる機能には以下の4つがあります。
(JSF2.2のJSRより)
- HTML 5 Friendly Markup
- Resource Library Contracts
- Faces Flows
- Stateless Views
2つ目の「Resource Library Contracts」に関して8/2にUS Oracleからチュートリアルが
出たようなのでやってみました。元々は「Multi-Templating」とわかりやすくカッコいい
名前だったものですが、どういう経緯で変わったかはよくわかってないです(^^;
チュートリアルのリンク
Oracle Learning Library : Java EE 7: Applying JSF 2.2 Resource Library Contracts
アクセスすると以下のようなページが表示されるので「Begin Tutorial」を押します。
以下のページが表示され、各ステップがバルーン式になっているので、上からやっていきます。
細かく確認したい方は是非直接チュートリアルベースに進めてください(^^;
ここでは抜粋というか、自分がやったメモ書きレベルで、翻訳をするわけではありませんm(_ _)m
追記:投稿してから「今日書いた量多いな…」と思ったのですが、手順を細かく書いただけで、やってることは単純です。JSFにおいて複数のテンプレートとCSSを用意して、それを動的にスイッチできるようにしてるだけです(^^)使うの面倒くさそうと思われませんように…
Overview
目安としては45分くらいでできるチュートリアルとのこと。
実際そんなにはかからない気もしますが(^^;
必要な環境としては
とありますが、Java SEは7u25かなと(^^;
昨日公開になったチュートリアルですが、たぶんその当時に書いたんですかね…今年は
updateが多すぎる(-_-;
ベースとなるコードはダウンロードできるようになっており「Prerequisites(必須条件)」にリンクがあります。
リンクをクリックして「JSFTemplateExampleApp.zip」を落とします。
解凍したフォルダをNetBeansProjects配下などに置きます。
NetBeans7.3.1を立ち上げて以下手順でプロジェクトファイルを読み込みます。
読み込めたら実行してみます。
以下のようなページが初期表示されて、adminページへのリンクとuserページへのリンクがあります。
adminページは
userページは
テンプレートでcssを読み込んでいて
すべて同じテンプレートを利用している構成になってます。
ではResource Library Contractsで複数のテンプレート、CSSを扱えるようにしていきます。
contractsフォルダの作成
以下のようにcontractsという名称のフォルダを作成します。
ここに各種templateやcssを突っ込んでいくようです。
プロジェクトの「Webページ」を右クリックして「新規」から「その他」を選びます(フォルダが選択肢にあればそれを選択)
カテゴリ「その他」のファイル・タイプ「フォルダ」を選択します
フォルダ名「contents」で終了します。
追加されればOKです。
contractsフォルダ配下にサブフォルダ作成
contractsフォルダを右クリックして、先ほど同様に新規(サブ)フォルダを追加します。
blue,green,redと3つ追加します。
resources配下をコピー
resourcesフォルダの配下にあるcssとテンプレートをコピーします。
blue,green,redのフォルダにペーストします。
ペーストしたcssLayout.cssを一部書き換えます。
書き換える対象はblueとgreenフォルダのcssのみです。
フォルダ |
#top background-color |
.center_content |
blue |
#0000FF |
#C0F7F9 |
green |
#03FF71 |
#F3C7F7 |
以下のような感じです(blueの場合)
さらにgreenの配下にあるdefault.cssに以下を追加します。
h3 {
font-family: Arial, "Arial CE", "Lucida Grande CE", lucida, "Helvetica CE", sans-serif;
border-bottom: 1px solid #AFAFAF;
font-size: 10px;
font-weight: bold;
margin: 0px;
padding: 0px;
color:#FF0314;
}
blue,green,redの配下にあるtemplate.xhtmlでlinkタグのパスを変更します。
blueの場合
<link href="${facesContext.externalContext.requestContextPath}/resources/default.css"
rel="stylesheet" type="text/css" />
<link href="${facesContext.externalContext.requestContextPath}/resources/cssLayout.css"
rel="stylesheet" type="text/css" />
↓
<link href="${facesContext.externalContext.requestContextPath}/contracts/blue/default.css"
rel="stylesheet" type="text/css" />
<link href="${facesContext.externalContext.requestContextPath}/contracts/blue/cssLayout.css"
rel="stylesheet" type="text/css" />
green,redもパスに合わせて同様に修正します。
resourcesフォルダ削除
resourcesフォルダを削除します。
というわけで、contractsの配下に置いた3パターンのcssやtemplateがリソースとして使うという流れです。
templateの参照を修正
resourcesフォルダを削除したので、以下の5ファイル
の中で定義されているtemplateへの参照を以下変更します。
<ui:composition template="/resources/template.xhtml">
↓
<ui:composition template="/template.xhtml">
faces-config.xmlの変更
faces-config.xmlを以下のapplicationタグを追加します。
<faces-config version="2.2"
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-facesconfig_2_2.xsd">
<application>
<resource-library-contracts>
<contract-mapping>
<url-pattern>/admin/*</url-pattern>
<contracts>blue</contracts>
</contract-mapping>
<contract-mapping>
<url-pattern>/user/*</url-pattern>
<contracts>green</contracts>
</contract-mapping>
<contract-mapping>
<url-pattern>*</url-pattern>
<contracts>red</contracts>
</contract-mapping>
</resource-library-contracts>
</application>
</faces-config>
マッピングは基本的に名前で行われるようですね(^^;
CDI管理対象Bean追加
テンプレートを動的に変更するためにCDI管理対象Beanを追加します。
まずはパッケージとして「com.example.beans」を以下の手順で追加します。
プロジェクトの「デフォルト・パッケージ」を右クリックして「新規」メニューから「その他」を選択します。
カテゴリ「Java」のファイル・タイプ「Javaパッケージ」を選択して「次へ」
パッケージ名「com.example.beans」を入力して「終了」します。
続けて、作成されたパッケージを右クリックして「新規」「その他」から
カテゴリ「JavaServer Faces」ファイル・タイプ「JSF管理対象Bean」を選択します。
TemplateBeanというクラス名にして、SessionScopedを選択します。
※なぜか自分の環境だと以下エラーが出ました(-_-;あり
クラスはできてるのですが、管理対象になってないPOJO…原因不明です。
まあ、自力で書けばいいので以下定義にします(^^;
package com.example.beans;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
@Named
@SessionScoped
public class TemplateBean implements Serializable{
private String contract = "red";
public String getContract() {
return contract;
}
public void setContract(String contract) {
this.contract = contract;
}
}
画面でテンプレートの切り替え選択ができるように、トップページのindex.xhtmlを以下定義とします。
<?xml version='1.0' encoding='UTF-8' ?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<body>
<ui:composition template="/template.xhtml">
<ui:define name="content">
<a href="#{facesContext.externalContext.requestContextPath}/faces/admin/index.xhtml">Go to</a> Admin Page
<h:panelGrid columns="1">
<p/>
<h2> Welcome to Home Page of ExampleApp Application </h2>
<p/><p/>
Choose a template for User Page:<br/>
<h:form>
<h:selectOneRadio value="#{templateBean.contract}" layout="pageDirection" required="true">
<f:selectItem itemValue="red" itemLabel="Red Header and Grey Body"/>
<f:selectItem itemValue="green" itemLabel="Green Header and Mauve Body"/>
</h:selectOneRadio>
<h:commandButton value="Apply" action="/user/index" />
</h:form>
</h:panelGrid>
</ui:define>
</ui:composition>
</body>
</html>
viewタグ追加
長かったですが、これが最後です。
以下2ファイル
に以下の位置にviewタグを追加します。
<f:view contracts="#{templateBean.contract}">
<ui:composition template="/template.xhtml">
...
</f:view>
実行!
さてやっとこ…終わった(^^;ふぅ
実行すると以下の画面が表示されます。
まずは上にあるadminへのリンクを押してみます。
blueフォルダのtemplateとCSSで表示されてます。
ではまたトップ画面に戻って、ラジオボタンの選択を下に変更します。
Applyボタンを押下すると
greenフォルダのtemplateとCSSで表示されています。
チュートリアルの修正
表示されたのを見て気づきましたが、チュートリアルのほうではヘッダの文字がちゃんと「Red」「Blue」「Green」と変わってますが、その手順はなかったような…(見逃していたらすみません)
というわけで、一応、それぞれのテンプレートを書き換えて再度実行。
ヘッダの文言を「赤」に修正
ヘッダの文言を「青」に修正
ヘッダの文言を「緑」に修正
というわけで、ちゃんと複数のテンプレートがつかえています(^^)
「PrimeFacesのテーマも似たようなことできるじゃん?」と一瞬思うかもしれませんが、テーマではCSSを変えることはできても、テンプレートを動的に変えることはできなかったので、そこが大きく違うかと思います。