[Spring Boot + Thymeleaf] Thymeleaf属性の使い方まとめ

# Thymeleafを使用した属性の宣言と使用方法実例について
Thymeleafを使用したhtmlでの属性の宣言と、その使用方法について実例合わせて載せていきます。

SpringBoot＋Thymeleafの組み合わせはWeb開発でよく使われるフレームワークですが、これらについて簡略的に使用法をまとめているサイトが意外と少なく、このページでできる限りまとめていきたいと思います。

## Themeleafとは？
SplingBootが標準で使うHTMLのテンプレートエンジン。
テンプレートエンジンとは、HTMLのテンプレートとデータを合成して、HTMLを作成してくれる機能。

例として挙げると「エラーが発生したときだけ作成するタグを宣言する」「JavaのListをループする」という、今まではJSPを使用してHTMLの中にJavaコードを書かなければいけなかった処理をHTML属性の宣言に近い形で実現できる。（HTMLの可読性が高くなる）

## 共通事項
Thymeleafを使用するためには、HTML内で宣言が必要。

```html:sample.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
～
</html>
```
上記の宣言をすると、「th:属性名」の形式でThymeleafを使用できる。

## 属性と実例

### th:text
Modelに登録された値をtext要素に適用する。

**形式**
```
th:text="${Modelに登録されたキー名}"
```

**実例**
```html:sample.html
<div th:text="${sampleText}"></div>
```

事前にModelへの登録が必要。
以下の例だと画面に「サンプルテキスト」が出力される。
```java:SampleController.java
	@GetMapping("/signup")
	public String getSignUp(Model model,@ModelAttribute SampleForm form) {
		
		model.addAttribute("sampleText","サンプルテキスト");
		return "user/signup";
	}

```

### th:field
Javaクラスと画面入力内容をバインド（紐づけ）することができる。

**形式**
```
th:field="${{Modelに登録されたキー名}.{変数名}}"
```

**実例**
以下はテキストフィールドの入力内容をModelに反映するための設定例。
```html:sample.html
<input type="text"	class="form-control" th:field="${sampleForm.userId}"/>
```

後述のth:objectが書かれたタグ内であれば、Modelに登録されたキー名を省略可能。その場合、"$"ではなく"#"で宣言する。キー名が変更される場合に修正が大変になるので、基本は以下の形式で記載するのが一般的のはず。

```html:sample.html
<form id="signup-form" method="post" action="/user/signup"
		class="form-signup" th:object="${sampleForm}">

    <input type="text"	class="form-control" th:field="*{userId}"/>
</form>
```

### th:object
JavaのクラスオブジェクトとModelをバインドする。
バインドしたオブジェクトを介してModel⇔Java間でデータをやり取りできる。


**形式**
```
th:object="${{Modelに登録されたキー名}}"
```

**実例**
```html:sample.html
<form id="signup-form" method="post" action="/user/signup"
		class="form-signup" th:object="${sampleForm}">
```

Controller側でModelへのAddAtributeが必要。
```java:sampleController.java
import com.example.demo.form.SampleForm;

@Controller
@RequestMapping("/user")
public class SampleController {

	 public String postSignUp(Model model ,@ModelAttribute SampleForm form) {
    // 処理を記述
    }
}

```

Modelに登録されるキー名は、フォームクラス名の先頭を小文字にしたものが登録される（以下だと"sampleForm"が登録される）
```java:sampleForm.java
import lombok.Data;

@Data
public class SampleForm {

	private String userId;
	
	
}
```


### th:each
javaのListやMapを読み込み、繰り返し処理を行う。

**形式**
```
th:each="{任意の変数名}:${Modelに登録されたMap or Listの名称}"
```

**実例**

```html:sample.html
<div th:each="item:${sampleMap}">
    <span th:text="${item.key}"></span> 
	<span th:text="${item.value}"></span>
</div>
```

事前にModelへの登録が必要。
```java:SampleController.java
	@GetMapping("/signup")
	public String getSignUp(Model model,@ModelAttribute SampleForm form) {
		
		Map<Integer,String> map=new HashMap<>();
		map.put(1,"value1");
		map.put(2, "value2");
		model.addAttribute("sampleMap",map);
		return "user/signup";
	}

```


### th:errorclass
th:fieldで指定したフィールドでバリデーションなどのエラーが発生した場合に、この要素のclassが追加で適用される。

**形式**
```
th:errorclass="{任意のクラス名}"
```


**実例**
下記の例だと、「userId」フィールドでエラーが発生した場合は「is-invalid」のクラスが追加で適用される。
```html:sample.html
<input type="text"
	class="form-control" th:field="*{userId}" th:errorclass="is-invalid"/>
```


### th:errors
th:fieldで指定したフィールドでバリデーションなどのエラーが発生した場合に、エラーメッセージをタグ内に表示する。
**形式**
```
th:error="{任意の値}"
```


**実例**
```html:sample.html
<div class="invalid-feedback" th:errors="*{userId}"></div>
```

### th:if
条件判定を行い、trueの場合にth:ifが記載されたタグをhtmlに適用する。

**形式**
```
th:if="${条件式}"
```

**実例**
以下だとsampleMapのキーが"1"の時のみ、「keyが1です。」というspanタグが適用される。
```html:sample.html

<div th:each="item:${sampleMap}">
	<span th:text="${item.key}"></span> 
	<span th:text="${item.value}"></span>
	<span th:if="${item.key == 1}">
		keyが1です。
	</span>
</div>
```

### th:unless
条件判定を行い、falseの場合にth:unlessが記載されたタグをhtmlに適用する。

**形式**
```
th:unless="${条件分}"
```

**実例**
以下だとsampleMapのキーが"1"でない時のみ、「keyが1ではありません。」というspanタグが適用される。
```html:sample.html

<div th:each="item:${sampleMap}">
	<span th:text="${item.key}"></span> 
	<span th:text="${item.value}"></span>
	<span th:unless="${item.key == 1}">
		keyが1ではありません。
	</span>
</div>
```