기본적인 개발 방식
일반적으로 화면을 구성할 때 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 를 사용하게 된다면 꼭 추가로 기록해놓을 예정이다.
'Backend > Spring+Boot' 카테고리의 다른 글
Ajax와 @RequestBody, @ResponseBody (0) | 2021.08.04 |
---|---|
@RequestParam, @ModelAttribute 생략 (0) | 2021.08.04 |
의존성 주입시 중복되는 타입에 대한 처리 (0) | 2021.07.23 |
Spring에서 권장되는 의존성 주입 방법 (0) | 2021.07.23 |
RestClient 구성시 고려사항 (0) | 2021.07.20 |