우와한 개발자

[ Thymeleaf ] 타임리프(Thymeleaf)란? 설정과 표현식 종류 정리

by 우와한개발자

[ 타임리프 Thymeleaf ]

  • Java 언어 기반의 서버측 템플릿 엔진
  • 주로 웹 어플리케이션 개발에 사용
❓템플릿 엔진
- 지정된 템플릿양식과 데이터가 합쳐져 HTML문서를 출력하는 소프트웨어
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Thymeleaf 예시</title>
</head>
<body>

    <!-- 텍스트 출력 -->
    <h1 th:text="${user.name}">이름</h1>
    <p>[[${user.email}]]</p>

    <!-- 조건부 렌더링 -->
    <p th:if="${isAdmin}">관리자입니다.</p>
    <p th:unless="${isAdmin}">일반 사용자입니다.</p>

    <!-- 반복문 -->
    <table>
        <tr th:each="user, iterStat : ${userList}">
            <td th:text="${iterStat.count}"></td>
            <td th:text="${user.name}"></td>
            <td th:text="${user.email}"></td>
        </tr>
    </table>

    <!-- URL -->
    <a th:href="@{/user/{id}(id=${user.id})}">상세보기</a>

    <!-- 폼 바인딩 -->
    <form th:action="@{/user/save}" method="post" th:object="${user}">
        <input type="text"  th:field="*{name}" />
        <input type="email" th:field="*{email}" />
        <button type="submit">저장</button>
    </form>

</body>
</html>

 

1. 설정

1) build.gradle : 의존성 추가

implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

 

2) 기본 설정

  • 확장자 : .html 권장
  • 파일 위치 : src/main/resource/templates/
  • 모든 html 파일에 네임스페이스 추가
  • 타임리프 설정시 application.properties에 캐시 false로 두기
<html	xmlns:th="http://www.thymeleaf.org">

 

2. Thymeleaf 표준 표현식

표현식 문법 설명 사용 예시
Variable Expressions ${...} 변수 값을 출력할 때 사용 ${user.name}
Selection Variable Expressions *{...} 선택된 객체(현재 객체)의 값을 출력 *{name}
Message Expressions #{...} 국제화 메시지 출력 #{home.message}
Link URL Expressions @{...} URL 경로 생성 @{/home}
Fragment Expressions ~{...} 다른 템플릿 조각 포함 ~{layout/header}

 

1) 변수 표현식 ${}

  • 서버에서 전달된 데이터를 출력하는 표현식
<pth:text="${user.name}"></p> //user 객체의 name 값 출력

 

2) 메시지 표현식 #{}

  • src/main/resources 아래 messages.properties 계열 파일에 정의된 국제화 메시지를 출력하는 표현식
❓국제화 메시지(i18n message)
- 사용자 언어에 따라 다른 텍스트를 보여주는 기능
- Internationalization에서 i와 n 사이의 18개 = i18n ..^^
<pth:text="#{home.message}"></p>
# src/main/resources/messages.properties
home.message=환영합니다

 

  • src/main/resources 아래 특정 폴터를 두고 messages.properties 계열 파일을 둔다면 스프링이 이를 인식할 수 있게 application.properties에 spring.messages.basename 설정이 필요함
# src/main/resources/application.properties
# src/main/resources/i18n/message에 국제화메세지 파일두겠다는 의미
spring.messages.basename=i18n/message

 

3) 선택 변수 표현식 *{...}

  • th:object로 지정된 객체를 기준으로 필드에 접근하는 표현식
  • th:object와 반드시 함께 사용하며, 지정된 객체 안에서 ${객체.필드} 대신 *{필드}로 간결하게 접근 가능
<div th:object="${user}">
    <p th:text="*{name}"></p>
    <p th:text="*{email}"></p>
    <p th:text="*{phone}"></p>
</div>

 

4) URL 표현시 @{}

  • URL을 동적으로 생성하는 표현식
  • 컨텍스트 경로를 자동으로 포함하며, 경로 변수와 쿼리 파라미터를 함께 사용 가능
<!-- 기본 경로 -->
<a th:href="@{/user/list}">목록</a>

<!-- 경로 변수 -->
<a th:href="@{/user/{id}(id=${user.id})}">상세보기</a>
<!-- 결과: /user/1 -->

<!-- 쿼리 파라미터 -->
<a th:href="@{/user/list(page=1, size=10)}">목록</a>
<!-- 결과: /user/list?page=1&size=10 -->

<!-- 경로 변수 + 쿼리 파라미터 혼합 -->
<a th:href="@{/user/{id}/posts(id=${user.id}, page=1)}">게시글</a>
<!-- 결과: /user/1/posts?page=1 -->

 

5)프래그먼트 표현식 ~{}

  • 다른 HTML 파일에 정의된 프래그먼트(조각)를 가져와 삽입하는 표현식
  • 공통 레이아웃(header, footer, nav)을 분리해서 재사용할 때 사용
<!-- fragments/layout.html에 정의된 header 프래그먼트를 삽입 -->
<div th:replace="~{fragments/layout :: header}"></div>
<div th:replace="~{fragments/layout :: footer}"></div>

<!-- fragments/layout.html -->
<header th:fragment="header">
    <nav>공통 네비게이션</nav>
</header>

<footer th:fragment="footer">
    <p>공통 푸터</p>
</footer>

블로그의 정보

우와한개발자 님의 블로그

우와한개발자

활동하기