SpringBoot - thymeleaf layout dialect(tympeleaf 레이아웃 적용하기)

들어가기

예전에 spring4 레거시 프로젝트 + xml 설정환경에서 tymeleaf 템플릿 엔진과 thymeleaf layout dialect(tymeleaf 레이아웃)를 적용했었다. 이번에는 springboot에 thymeleaf와 thymeleaf layout dialect를 적용해 보겠다.

개발환경: java8, springboot2, spring5, maven

라이브러리 추가

pom.xml에 thymeleaf와 thymeleaf layout dialect를 추가하자.

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
<!--<version>2.3.0</version>-->
</dependency>

thymeleaf는 thymeleaf템플릿 엔진을 사용하기 위한 기초 라이브러리이며, thymeleaf-layout-dialect는 thymeleaf템플릿 엔진 기반 레이아웃을 구성할때 필요한 라이브러리이다. 자애로운 spring-boot-starter-parent께서 위 둘의 버전관리를 자동으로 해주시니, version을 생략해도 된다. 본인의 경우 2.1.1 버전이 적용되었다.

html파일로 레이아웃 구성

폴더구조와 html파일들

springboot web 프로젝트에서 기본적으로 resources/templates에서 뷰를 찾는다. template/layout/default.html은 thymeleaf의 레이아웃이 되는 파일이다. template/fragments/config.html template/fragments/footer.html template/fragments/header.html 파일은 defaout.html 레이아웃의 내부를 구성하는 부품 화면이 된다. template/index.html은 핵심인 contents가 되는 페이지이다.


default.html

이 파일이 thymeleaf 레이아웃을 잡아주는 핵심파일이 된다. head th:replace는 head 영역의 부속 페이지를 말한다. 부속페이지는 fragments/config(html을 생략한다.) 그리고 그 파일의 configFragment 태그를 잘라와 사용한다는 의미이다. header footer도 비슷한 의미이다. layout이 되는 html의 태그는 xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"를 삽입해야 한다. layout:fragment="content" 부분은 서버의 요청별로 달라지는 컨텐츠 페이지가 된다.(index.html)

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lagn="ko" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">

<head th:replace="fragments/config :: configFragment"></head>

<header th:replace="fragments/header :: headerFragment"></header>

<div layout:fragment="content"></div>

<footer th:replace="fragments/footer :: footerFragment"></footer>

</html>


config.html

head의 공통적인 부분을 담당하는 페이지이다. css, js 파일따위를 관리 할 수 있다. 특의한 점은 <th:block layout:fragment="css"></th:block> <th:block layout:fragment="script"></th:block> 인데, 레이아웃의 content가 되는 index.html에 작성된 css나, js를 가져와서 적용하는 부분이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">

<head th:fragment="configFragment">
<meta charset="UTF-8" />
<!-- 공통으로 쓰이는 css파일을넣는다.-->
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<!-- 컨텐츠페이지의 CSS 영역이 들어감 -->
<th:block layout:fragment="css"></th:block>

<!-- 공통으로 쓰이는 css파일을넣는다.-->
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<!-- 컨텐츠페이지의 스크립트 영역이 들어감 -->
<th:block layout:fragment="script"></th:block>
</head>

</html>


footer.html

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<footer th:fragment="footerFragment">

<div style="border: 1px solid gold">
Footer영역입니다.
</div>

</footer>

</html>


header.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<header th:fragment="headerFragment">

<div style="border: 1px solid green">
header.html 입니다.
</div>

<!-- <a th:href="@{/index}">index 페이지 이동</a>-->

</header>

</html>


index.html

컨텐츠가 되는 index.html 페이지이다. html 태그의 어트리뷰트가 다름을 주의하자. layout:decorator 로 이 페이지가 렌더링 될때 사용살 layout을 지정한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="layout/default">

<!-- index.html 고유 CSS 추가 -->
<th:block layout:fragment="css">
</th:block>

<!-- index.html 고유 스크립트 추가 -->
<th:block layout:fragment="script">
</th:block>

<div layout:fragment="content">

<div style="border: 1px solid red">
index.html 입니다.
</div>

</div>
</html>

실행결과

springboot thymeleaf 레이아웃 적용 결과

간단하게 동작을 확인할 수 있다. spring개발팀이 밀고 있어써 그런지 thymeleaf의 설정법은 기타 템플릿 엔진보다 간편한것 같다.

끝!