Backend/Spring+Boot

Thymeleaf 훑어보기

findmypiece 2021. 7. 30. 01:35
728x90

기본적인 개발 방식

일반적으로 화면을 구성할 때 top, footer 영역은 거의 변하지 않고 content 영역만 달라진다. 이에 Thymeleaf 는 기본적으로 top, content, footer 의 배치가 정의된 레이아웃을 html 로 미리 만들어 놓고 이를 이용해서 실제 페이지를 만드는 방식을 사용한다. 

 

레이아웃도 여러개를 만들어서 사용할 수 있고 여기에 사용되는 top, footer 는 거의 변하지 않으므로 일반적으로 특정 html 로 생성해놓고 재활용하는데 이를 컴포넌트라고 명명한다. 이는 jsp 의 include 방식과 비슷하다.

 

결국 레이아웃에는 top, content, footer 가 정의되어 있지만 content 의 실제 구현부는 비어있는 상태로 정의되고 실제 페이지 개발시 content 의 구현부를 정의해서 화면을 개발하게 된다.

 

활용예시

연동방법은 찾아보면 많이 나오니 여기에서는 기본적인 사용법만 다뤄본다. SpringBoot 기준 디렉토리 구조는 대략 아래와 같다.

WEB-INF
  ⌙ views
    ⌙ fragments
      ⌙ head.html
      ⌙ top.html
      ⌙ footer.html
    ⌙ layout
      ⌙ commonLayout.html
    test.html

views/fragments 디렉토리 하위에 공통으로 사용할 컴포넌트를 정의하고 이를 사용하는 레이아웃은 views/layout 디렉토리 하위에 정의한다. 실제 구현 페이지는 test.html 에서는 레이아웃을 사용해서 content에 해당하는 내용만 구현해서 사용될 것이다. 각 구현을 예시는 다음과 같다.

 

컴포넌트 생성

html 태그 안에 thymeleaf 사용을 위한 스키마를 정의해주고 th:fragment 속성으로 컴포넌트 이름을 지정하면 된다.

 

head.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="headFragment">
	<title>타이틀입니다.</title>
</head>
</html>

 

top.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
	<div th:fragment="topFragment">
		top 영역입니다.
	</div>
</html>

 

footer.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
	<div class="footer" th:fragment="footerFragment">
		footer 영역입니다.
	</div>
</html>

 

레이아웃 생성

html 태그 안에 thymeleaf 사용을 위한 스키마를 정의해준다. 여기에서는 thymeleaf/layout 스키마가 추가되었다. 

th:replace 속성으로 해당 영역을 대체할 컴포넌트를 정의한다. jsp의 include 와 비슷하다고 생각하면 된다.

실제 페이지에서 정의할 content 영역은 layout:fragment 속성으로 정의하는데 구현부 없이 선언만 해 놓는다.

 

commonLayout.html

<!DOCTYPE html>
<html lang="ko"
	  xmlns:th="http://www.thymeleaf.org"
	  xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">

	<head th:replace="fragments/head :: headFragment"></head>

	<body>
		<div th:replace="fragments/top :: topFragment"></div>
		<div layout:fragment="content"></div>
		<div th:replace="fragments/footer :: footerFragment"></div>
	</body>

</html>

 

실제 페이지 구현

html 태그의 data-layout-decorate 속성을 통해 사용할 레이아웃을 지정한다.

레이아웃에서 정의만 했던 layout:fragment 의 구현부를 추가로 정의해서 페이지를 완성한다.

test.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
	  xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
	  data-layout-decorate="~{layout/commonLayout}" >
	<div layout:fragment="content">
		컨텐츠입니다.
	</div>
</html>

 


Thymeleaf 에는 th:block 라는 속성이 있는데 좀 특이해서 추가로 정리한다. Thymeleaf가 제공하는 모든 th:xxx 속성들은 말그대로 요소가 아니라 속성이기 때문에 사용하려면 기본적으로 기존 html 태그에 의존적이다. 그런데 지정할 html 태그가 마땅치 않은 경우가 있다. 

 

예를 들어 아래와 같은 영역이 있는데 숫자영역을 천단위 , 로 포맷팅된 숫자 문자열만을 랜딩하고 싶은 경우를 생각해보자.

<div>
  총 123123123 건
<div>

 

Thymeleaf 에는 이를 처리할 수 있는 아래와 같은 속성이 존재한다.

th:text="${#numbers.formatInteger(totalCount, 0, 'COMMA')}"


이에 기본적으로 아래와 같이 처리할 수 있다.

<div>
  총 <span th:text="${#numbers.formatInteger(totalCount, 0, 'COMMA')}">123123123</span> 건
<div>

 

그런데 th:block 를 사용할 경우 아래와 같이 할 수도 있다.

<div>
  총 <th:block th:text="${#numbers.formatInteger(totalCount, 0, 'COMMA')}">123123123</th:block> 건
<div>

 

사실 Tyhmeleaf 를 많이 활용해본 게 아니라 th:block 가 언제 필요한지 정확히는 모르겠다. 현재로선 굳이 th:block 를 사용하지 않더라도 어찌하든 html 태그로 지정이 가능할 거 같기 때문이다. 만약 진짜 사용할 html 태그가 없어서 th:block 를 사용하게 된다면 꼭 추가로 기록해놓을 예정이다.

728x90