【JSF】テンプレート

# JSFテンプレート

テンプレートは、アプリケーション内の他のページのベースまたはテンプレートとして機能するページを作成できる便利なFacelets機能です。
テンプレートを使用することで、コードを再利用して、同じようなページを何度も再作成することを回避できます。
ページ数が多いアプリケーションで標準のルックアンドフィールを維持するのにも役立ちます。

| タグ | 機能 |
|:--|:--|
|ui:component| コンポーネントツリーに追加されるコンポーネントを定義します。|
|ui:composition|オプションでテンプレートを使用するページ構成を定義するために使用されます。このタグの外側のコンテンツは無視されます。|
|ui:decorate|これはcompositionタグに似ていますが、このタグ以外のコンテンツを無視しません。|
|ui:fragment|これはcomponentタグに似ていますが、このタグ以外のコンテンツを無視しません。|
|ui:define|テンプレートによってページに挿入されるコンテンツを定義します。|
|ui:include|複数のページのコンテンツをカプセル化して再利用します。|
|ui:insert|テンプレートにコンテンツを挿入するために使用されます。name属性で識別します。|
|ui:param|インクルードされたファイルにパラメーターを渡すために使用されます。|

## テンプレートファイル
ui:insertタグとname属性を用いて、対応するセクションを挿入する場所を設定します。
テンプレートファイルには、全ページ共通のタグ等を設定します。

```HTML:WEB-INF/template.xhtml
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://xmlns.jcp.org/jsf/html"
	xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>
	<ui:insert name = "html_header">
		<title>テンプレート</title>
	</ui:insert>
</h:head>

<h:body>

	<div
		style="border-width: 2px; border-color: blue; border-style: solid;">
		<ui:insert name="header">
			<ui:include src="/templates/header.xhtml" />
		</ui:insert>
	</div>
	<br />
	<div
		style="border-width: 2px; border-color: black; border-style: solid;">
		<ui:insert name="content">
			<ui:include src="/templates/contents.xhtml" />
		</ui:insert>
	</div>
	<br />

	<div style="border-width: 2px; border-color: red; border-style: solid;">

		<ui:insert name="footer">
			<ui:include src="/templates/footer.xhtml" />
		</ui:insert>
	</div>
</h:body>
</html>
```

### ヘッダ部
テンプレートとして使用するデフォルトのセクションを準備します。
まずは、ヘッダ部です。

```HTML:templates/header.xhtml
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://xmlns.jcp.org/jsf/html"
	xmlns:ui="http://java.sun.com/jsf/facelets">

	<ui:composition>
		<h1>デフォルト ヘッダー</h1>
	</ui:composition>

</html>
```

### コンテンツ部
続いて、コンテンツ部です。

```HTML:templates/contents.xhtml
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://xmlns.jcp.org/jsf/html"
	xmlns:ui="http://java.sun.com/jsf/facelets">

	<ui:composition>
		<h1>デフォルト コンテンツ</h1>
	</ui:composition>

</html>
```

### フッタ部
最後に、フッタ部です。

```HTML:templates/footer.xhtml
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://xmlns.jcp.org/jsf/html"
	xmlns:ui="http://java.sun.com/jsf/facelets">

	<ui:composition>
		<h1>デフォルト フッター</h1>
	</ui:composition>

</html>
```

### テンプレートデフォルト
テンプレートデフォルトのページを作るには、次のようなxhtmlを作成します。
ui:compossion タグのtemplate属性を使用することで、テンプレートとして使用するファイルを指定します。

```HTML:default.xhtml
<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml"   
   xmlns:h = "http://java.sun.com/jsf/html"
   xmlns:ui = "http://java.sun.com/jsf/facelets">
   
   <h:body>
      <ui:composition template = "WEB-INF/template.xhtml">	
      </ui:composition>
   </h:body>
</html>	
```

動作例は次のようになります。
![pic013.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292074/68226c65-1f3b-c9d4-4438-3dd3d8e91322.png)

### 独自コンテンツの作成
テンプレートが作成できたので、テンプレートを置き換える独自コンテンツを作成します。
ui:compossion タグのtemplate属性を使用するのは同じですが、
テンプレートを置き換えるには、ui:define タグでオーバーライド(置き換える部分)する部分を作成します。

```HTML:home.xhtml
<!DOCTYPE html>

<html xmlns = "http://www.w3.org/1999/xhtml"   
   xmlns:h = "http://java.sun.com/jsf/html"
   xmlns:ui = "http://java.sun.com/jsf/facelets">
   
   <h:body>
      <ui:composition template = "WEB-INF/template.xhtml">	
    	<ui:define name="html_header">
    		<title>ホーム</title>
    	</ui:define>
      
        <ui:define name = "content">				
			<h:link value = "Page 1" outcome = "page1" />
			<h:link value = "Page 2" outcome = "page2" />			
		</ui:define>
      </ui:composition>
   </h:body>
</html>	
```

```HTML:page1.xhtml
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:ui="http://java.sun.com/jsf/facelets">

	<h:body>
		<ui:composition template = "WEB-INF/template.xhtml">
      		<ui:define name="html_header">
      			<title>ページ１</title>
      		</ui:define>

			<ui:define name="header">
				<h2>Page1 header</h2>
			</ui:define>
	
			<ui:define name="content">
				<h2>Page1 content</h2>
				<h:link value="Back To Home" outcome="home" />
			</ui:define>
	
			<ui:define name="footer">
				<h2>Page1 Footer</h2>
			</ui:define>
		</ui:composition>
	</h:body>
</html>
```

```HTML:page2.xhtml
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:ui="http://java.sun.com/jsf/facelets">

	<h:body>
		<ui:composition template = "WEB-INF/template.xhtml">
      		<ui:define name="html_header">
      			<title>ページ２</title>
      		</ui:define>

			<ui:define name="header">
				<h2>Page2 header</h2>
			</ui:define>
	
			<ui:define name="content">
				<h2>Page2 content</h2>
				<h:link value="Back To Home" outcome="home" />
			</ui:define>
	
			<ui:define name="footer">
				<h2>Page2 Footer</h2>
			</ui:define>
		</ui:composition>
	</h:body>
</html>
```

home.xhtml、page1.xthml、page2.xhtml のページを表示した例は次のようになります。

ホーム画面
![pic014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292074/1789432a-053c-c259-d43b-ba9eaba64839.png)

ページ１
![pic015.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292074/efe0dccf-e4ef-dfcd-bab7-0032a830ce70.png)

ページ２
![pic016.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292074/a97b07c2-e7ed-c0e8-8f48-370e02b23252.png)

## 参考
[JSF - template tags](https://www.tutorialspoint.com/jsf/jsf_templates_tag.htm)