이 글은 인프런 김영한님의 Spring 강의를 바탕으로 개인적인 정리를 위해 작성한 글입니다.


타임리프(Thymeleaf)의 템플릿 조각 기능은 HTML 문서의 특정 부분을 재사용 가능한 형태로 정의하고, 이를 다른 템플릿에서 삽입하여 사용할 수 있게 해준다.

이 기능은 중복을 줄이고, 템플릿의 유지보수를 용이하게 만들어준다. 템플릿 조각은 주로 헤더, 푸터, 네비게이션 바 등의 반복적으로 사용되는 UI 컴포넌트를 만들 때 유용하다.

 

템플릿 조각 정의하기

템플릿 조각은 th:fragment 속성을 사용하여 정의한다. 예를 들어, 하나의 HTML 파일 내에 여러 조각을 정의할 수 있다.

<!-- header.html -->
<div th:fragment="headerFragment">
  <header>
    <!-- 헤더 내용 -->
  </header>
</div>

<div th:fragment="footerFragment">
  <footer>
    <!-- 푸터 내용 -->
  </footer>
</div>

 

템플릿 조각 사용하기

다른 템플릿에서 이 조각을 사용하고 싶다면 th:replace 또는 th:insert 속성을 사용하여 해당 조각을 삽입한다.

  • th:replace는 현재 태그를 대상 템플릿 조각으로 완전히 대체한다.
  • th:insert는 대상 템플릿 조각을 현재 태그 내부에 삽입한다.
<!-- index.html -->
<div th:replace="header.html::headerFragment"></div>
<div th:insert="footer.html::footerFragment"></div>

 

조각 표현식

템플릿 조각을 참조할 때 사용하는 표현식은 템플릿명::조각명 형식을 따른다. 템플릿명은 조각이 정의된 파일의 이름이며, 조각명은 해당 파일 내에서 th:fragment로 정의된 조각의 이름이다.

th:fragment 가 있는 태그는 다른곳에 포함되는 코드 조각으로 이해하면 된다.

 

파라미터 전달하기

템플릿 조각에 파라미터를 전달하여 동적인 내용을 생성할 수도 있다. 이를 위해 조각을 정의할 때 파라미터를 명시하고, 조각을 사용할 때 파라미터 값을 전달한다.

<!-- header.html -->
<div th:fragment="headerFragment (title)">
  <header>
    <h1 th:text="${title}">기본 타이틀</h1>
  </header>
</div>

<!-- index.html에서 조각 사용하며 파라미터 전달 -->
<div th:replace="header.html::headerFragment (${pageTitle})"></div>

 

예시

컨트롤러

@GetMapping("/fragment")
public String template() {
    return "template/fragment/fragmentMain";
}

 

footer/html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
    <body>
        <footer th:fragment="copy"> <!-- 이렇게 설정하면 함수 쓰듯이 copy 라는 이름으로 호출할 수 있다. (템플릿 조각) -->
            푸터 자리 입니다.
        </footer>

        <footer th:fragment="copyParam (param1, param2)"> <!-- copyParam 라는 이름으로 파라미터를 사용할 수 있게 해준다.(템플릿 조각) -->
            <p>파라미터 자리 입니다.</p>
            <p th:text="${param1}"></p>
            <p th:text="${param2}"></p>
        </footer>
    </body>
</html>

 

fragmentMain.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
    <body>
        <h1>부분 포함</h1>

        <h2>부분 포함 insert</h2>
        <div th:insert="~{template/fragment/footer :: copy}"></div> <!-- div 태그 안에 copy 를 넣음 -->

        <h2>부분 포함 replace</h2>
        <div th:replace="~{template/fragment/footer :: copy}"></div> <!-- div 태그를 copy 가 대체함 -->

        <h2>부분 포함 단순 표현식</h2>
        <div th:replace="template/fragment/footer :: copy"></div> <!-- copy 가 단순하다면 ~{} 생략 가능 -->

        <h1>파라미터 사용</h1>
        <div th:replace="~{template/fragment/footer :: copyParam ('데이터1', '데이터2')}"></div> <!-- copyParam 템플릿 조각 으로 div 태그 대체 -->
    </body>
</html>

 

결과

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
    <body>
        <h1>부분 포함</h1>

        <h2>부분 포함 insert</h2>
        <div><footer> <!-- 이렇게 설정하면 함수 쓰듯이 copy 라는 이름으로 호출할 수 있다. (템플릿 조각) -->
            푸터 자리 입니다.
        </footer></div> <!-- div 태그 안에 copy 를 넣음 -->

        <h2>부분 포함 replace</h2>
        <footer> <!-- 이렇게 설정하면 함수 쓰듯이 copy 라는 이름으로 호출할 수 있다. (템플릿 조각) -->
            푸터 자리 입니다.
        </footer> <!-- div 태그를 copy 가 대체함 -->

        <h2>부분 포함 단순 표현식</h2>
        <footer> <!-- 이렇게 설정하면 함수 쓰듯이 copy 라는 이름으로 호출할 수 있다. (템플릿 조각) -->
            푸터 자리 입니다.
        </footer> <!-- copy 가 단순하다면 ~{} 생략 가능 -->

        <h1>파라미터 사용</h1>
        <footer> <!-- copyParam 라는 이름으로 파라미터를 사용할 수 있게 해준다.(템플릿 조각) -->
            <p>파라미터 자리 입니다.</p>
            <p>데이터1</p>
            <p>데이터2</p>
        </footer> <!-- copyParam 템플릿 조각 으로 div 태그 대체 -->
    </body>
</html>