본문 바로가기

Server Programming/Spring Boot Backend Programming

5장-2. Thymeleaf

반응형

JSP를 대신하는 템플릿 라이브러리 Thymeleaf 

Thymeleaf 사용을 위한 네임스페이스 지정

<html lang="en" xmlns:th="http://www.thymeleaf.org">

 

Model에 담긴 데이터 사용시 변수 찾지 못하는 에러 해제

: Settings- Thymeleaf - Unresolved references in Thymeleaf expression variables

 

 

Thymeleaf 순서

  • 출력 : 'th :', 인라인 '[[${~}]]'
  • 변수 선언 : with
  • 반복문과 제어문 : each, 삼항연산자, Switch
  • 링크 처리 : '@', 쿼리스트링, URLEncoding
  • 고유한 기능 : 인라인, 레이아웃

 

 


Thymeleaf 출력

Model에 담긴 데이터 출력 방법

  1. 'th: '로 시작하는 속성 이용
  2. 인라인 이용

 

(1) 출력 테스트를 위해 컨트롤러에 ex1() 메서드 작성

package org.zerock.b01.controller;

import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Arrays;
import java.util.List;

@Controller
@Log4j2
public class SampleController {
    @GetMapping("/hello")
    public void hello(Model model){
        log.info("hello...");

        model.addAttribute("msg", "HELLO WORLD");
    }

    @GetMapping("/ex/ex1")
    public void ex1(Model model){
        log.info("타임리프 출력하는 두가지 방식 테스트...");
        List<String> list= Arrays.asList("AAA", "BBB", "CCC","DDD");

        model.addAttribute("list", "list");
    }
}

 

(2) ex1.html 작성

<!-- 타임리프 네임스페이스를 이용한 출력-->
<h4 th:text="${list}"> </h4>
<!-- 인라인을 이용한 출력-->
<h4> [[${list}]]</h4>

Thymeleaf 변수 선언

<!-- th:with을 이용한 변수 선언-->
<div th:with="num1 = ${10}, num2=${20}">
    <h4 th:text="${num1+num2}"></h4>
</div>

Thymeleaf 반복문과 제어문

반복문

<!-- 해당 태그에 'th:each' 태그 이용 -->
<ul>
    <li th:each="str: ${list}" th:text="${str}"></li>
</ul>
<!-- 별도의 태그인 'th:block' 이용-->
<ul>
    <th:block th:each="str: ${list}">
        <li>[[${str}]]</li>
    </th:block>
</ul>

<!-- 반복문에서 상태를 관리하는 status 변수-->
<!-- index/count/size/first/last/odd/even -->

<ul>
    <!-- index : 0부터 시작하는 기수-->
    <li th:each="str, status: ${list}">
        [[${status.index}]] -- [[${str}]]
    </li>
    <!-- count : 1부터 시작하는 기수-->
    <li th:each="str, status: ${list}">
        [[${status.count}]] -- [[${str}]]
    </li>
</ul>

제어문

<!-- 타임리프 제어문 : th:if/th:unless/th:switch-->
<ul>
    <li th:each="str, status :${list}">
        <!-- 만약~라면-->
        <span th:if="${status.odd}">ODD --[[${str}]]</span>
        <!-- 만약~이 아니라면-->
        <span th:unless="${status.odd}">EVEN --[[${str}]]</span>
    </li>
</ul>

삼항연산자

<!-- 삼항 연산자 이용-->
<ul>
    <li th:each="str, status :${list}">
        <span th:text="${status.odd} ?'ODD --'+${str} : 'EVEN --'+${str}"></span>
    </li>
</ul>

Switch문 (+case)

<!-- switch문 처리 (+case)-->
<ul>
    <li th:each="str, status:${list}">
        <!-- 반복구간 : 3-->
        <th:block th:switch="${status.index % 3}">
            <span th:case="0">0</span>
            <span th:case="1">1</span>
            <span th:case="2">2</span>
        </th:block>
    </li>
</ul>

Thymeleaf 링크 처리

JSTL보다 편리한 링크 처리 기능 지원

: '()'을 이용한 쿼리스트링, 자동 URLEncoding

<!-- '@'를 이용한 링크 처리-->
<!-- 기본-->
<a th:href="@{/hello}">Go to /hello</a>

 

<!--'()'로 쿼리스크링을 구현한 링크 처리-->
<a th:href="@{/hello(name='AAA', age=16)}"> Go to /hello</a>
<!--: /hello?name=AAA%age=16-->

 

<!-- JSP와 다르게 자동으로 URLEncoding이 수행된다.-->
<a th:href="@{/hello(name='한글처리', age=16)}"> Go to /hello</a>

 

<!-- 배열같이 이름이 같은 여러 파라미터들로 이루어진 경우-->
<a th:href="@{/hello(types=${ {'AA', 'BB', 'CC'} }, age=16)}"> Go to /hello</a>
<!--: /hello?types=AA&types=BB&&types=CC&age=16-->

 


Thymeleaf의 고유한 기능

  1. 인라인 처리
  2. 레이아웃 구성

인라인 처리

인라인

: 상황에 따라 동일한 데이터를 다르게 출력하는 기능으로 자바스크립트와 함께 사용한다.

 

(1) 다양한 종류의 데이터를 담은 SampleDTO 작성

package org.zerock.b01.dto;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;

@Data
@Log4j2
@AllArgsConstructor
@NoArgsConstructor
public class SampleDTO {
    public String p1, p2, p3;
}

 

(2) SampleController에 SampleDTO를 Model에 담아 전달하는 ex2() 작성

-List<>에 IntStream을 이용해 데이터를 담는다.

-Map에 데이터를 담는다.

-SampleDTO 인스턴스 생성해 데이터를 담는다.

-URL패턴에 대해 데이터를 담은 자료구조들을 model에 담아 전달한다.

 

@GetMapping("/ex/ex2")
public void ex2(Model model){
    log.info("ex/ex2...");

    List<String> strList = IntStream.range(1, 10)
            .mapToObj(i -> "Data"+i)
            .collect(Collectors.toList());

    model.addAttribute("list", strList);

    Map<String, String> map = new HashMap<>();
    map.put("A", "AAA");
    map.put("B", "BBB");

    model.addAttribute("map",map);

    SampleDTO sampleDTO =new SampleDTO();
    sampleDTO.p1 ="Value --p1";
    sampleDTO.p2 ="Value --p2";
    sampleDTO.p3 ="Value --p3";

    model.addAttribute("dto", sampleDTO);
}

 

(3) ex2.html 작성

 

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div th:text="${list}"></div>
<div th:text="${map}"></div>
<div th:text="${dto}"></div>

<script th:inline="javascript">
  const list = [[${list}]]

  const map = [[${map}]]

  const dto = [[${dto}]]

  console.log(list);
  console.log(map);
  console.log(dto);

</script>

</body>
</html>

 

출력 결과

[Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9]
{A=AAA, B=BBB}
SampleDTO(p1=Value --p1, p2=Value --p2, p3=Value --p3)

Thymeleaf의 레이아웃 기능

(1) 의존성 추가 - 버전 명시하지 않고 사용

implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'

 

(2) templates/layout에 레이아웃을 위한 layout1.html 작성

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
    <meta charset="UTF-8">
    <title>Layout Page</title>
</head>
<body>
<div>
  <h3>Sample Layout Header</h3>
</div>

<!-- 다른 파일에서 가져와 코드 재활용 가능-->
<div layout:fragment="content">
  <p>Page content goes here</p>
</div>

<div>
  <h3>Sample Layout Footer</h3>
</div>

<!-- 다른 파일에서 가져와 코드 재활용 가능-->
<th:block layout:fragment="script">
  
</th:block>

</body>
</html>

 

(3) layout1을 사용할 ex3.html 작성

-레이아웃 네임스페이스를 지정하고, decorate 속성을 이용해 레이아웃 사용

-'~{}'를 이용하면 현재 위치 경로부터 시작한다.

-'layout:fragment'를 이용해 레이아웃 중 원하는 부분에 화면을 추가/수정할 수 있다.

 

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layout/layout1.html}">

<div layout:fragment="content">

  <h1>ex3.html</h1>

</div>

<script layout:fragment="script" th:inline="javascript">

  const arr = [[${arr}]]

</script>

-> inline 기능을 이용해 화면에 나타나진 않는 빌트인 속성을 사용할 수 있다.

 

반응형