Java/Spring

[Thymeleaf] 타임리프 header와 footer 관리하기

LimeCoding 2023. 9. 12. 13:05

처음엔 가장 사용하기 쉬운 mustache를 이용하여 header와 footer를 중복해서 쓰지 않는 방법을 배웠다. 그러나 스프링 진영에 공식적으로 밀고있는 타임리프는 아직 사용방법이 미숙하여 관리하는 법을 모르고있었는데 책을 읽다 알게 되어 정리하려고 한다.

 

먼저 Thymeleaf layout dialect를 의존성에 추가한다.

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

 

그리고 header, footer, layout, index 파일을 만들어준다.

스프링에서는 resources 밑에 자원을 넣는다. 폴더 구조를 잘 보고 주의해서 넣자!

각 파일의 코드는 다음과 같다.

 

header 파일

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

footer 파일

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

 

layout 파일

<!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>Title</title>

    <th:block layout:fragment="script"></th:block>
    <th:block layout:fragment="css"></th:block>
</head>
<body>
<div th:replace="fragments/header::header"></div>

<div layout:fragment="content">
    layout1의 본문 영역입니다.
    지정된 fragment가 없으면 이게 나옵니다
</div>

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

</body>
</html>

 

main 파일

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

<div layout:fragment="content">
    예제의 본문 영역입니다.
    fragment가 존재하면 layout1의 fragment를 대체합니다
</div>

</html>

 

 

header파일 <div layout:fragment="header"> 

 이 태그에 감싸져있는 부분이 하나의 html 조각이라고 생각하면 된다.

 

layout 파일 <div th:replace="fragments/header::header">

위에서 선언한 header fragment를 replace를 통해 가지고 온다. 그러면 해당 html 코드는 가져온 html 코드로 대체된다.

 

main 파일 layout:decorate="~{layouts/layout}"

layouts 폴더 밑에 layout 파일을 적용하기 위해 네임스페이스를 추가해 준다. 정확하진 않지만 가져온다고 생각하면 편할 것 같다.

 

main 파일, layout 파일 <div layout:fragment="content">

content로 fragment를 선언한다. 이때 두 파일에 다 존재하면 main에 있는 내용이 layout의 내용을 대체한다. layout에만 존재하는 경우에는 layout의 내용을 보여준다. main에만 있는 경우에는 그 내용이 보이지 않는다. 추측으로는 layout이 구조를 구성하고 해당 태그와 동일한 태그가 있으면 대체하는 형식인 것 같다.