inblog logo
|
LifeLog, DevLog
    Spring

    Thymeleaf

    KYJTHEYJ's avatar
    KYJTHEYJ
    Dec 24, 2025
    Thymeleaf
    Contents
    Thymeleaf주요 문법

    Thymeleaf

    스프링부트의 공식 View를 보여주는 서버 사이드 템플릿 엔진

    주요 문법

    HTML 태그 안에 붙여 사용한다

    전달한 모델의 어트리뷰트는 ${} 로 감싸 꺼낸다

    • th:text, th:utext, [[…]]

      // 일반 텍스트 출력
      <p th:text="${user.name}">홍길동</p>
      
      // 만약 부가적인 HTML 태그를 붙여 출력하는 경우에 사용함
      <p th:utext="${htmlContent}">내용</p>
      
      // 인라인 표현
      <p>이름: [[${user.name}]]</p>
    • th:href, th:src

      <!-- URL -->
      <a th:href="@{/users/{id}(id=${user.id})}">상세보기</a>
      <!-- 결과: <a href="/users/1">상세보기</a> -->
      
      <!-- 쿼리 파라미터 -->
      <a th:href="@{/search(keyword=${keyword}, page=1)}">검색</a>
      <!-- 결과: <a href="/search?keyword=spring&page=1">검색</a> -->
      
      <!-- 이미지 -->
      <img th:src="@{/images/product/{id}.jpg(id=${product.id})}" />
      <!-- 결과: <img src="/images/product/123.jpg" /> -->
    • th:class, th:style, th:attr

      <!-- 조건부 클래스 -->
      <div th:class="${user.active} ? 'active' : 'inactive'">상태</div>
      
      <!-- 여러 클래스 -->
      <div th:classappend="${user.vip} ? 'vip-badge' : ''">사용자</div>
      
      <!-- 스타일 -->
      <span th:style="'color:' + ${product.stock > 0 ? 'green' : 'red'}">
          재고
      </span>
      
      <!-- 모든 속성 설정 가능 -->
      <input type="text" th:attr="value=${user.name}, placeholder='이름 입력'" />
      
      <!-- 또는 개별 지정 (더 간단) -->
      <input type="text" 
             th:value="${user.name}" 
             th:placeholder="'이름 입력'" />
    • th:each

      <!-- 기본 -->
      <div th:each="user : ${users}">
          <p th:text="${user.name}">이름</p>
      </div>
      
      <!-- 인덱스 사용 -->
      <tr th:each="product, stat : ${products}">
          <td th:text="${stat.index}">0</td>      <!-- 0부터 시작 -->
          <td th:text="${stat.count}">1</td>      <!-- 1부터 시작 -->
          <td th:text="${product.name}">상품명</td>
      </tr>
      
      <!-- stat 정보 -->
      <!-- stat.index: 0부터 시작하는 인덱스 -->
      <!-- stat.count: 1부터 시작하는 카운트 -->
      <!-- stat.size: 전체 개수 -->
      <!-- stat.first: 첫 번째인지 (boolean) -->
      <!-- stat.last: 마지막인지 (boolean) -->
      <!-- stat.even: 짝수인지 (boolean) -->
      <!-- stat.odd: 홀수인지 (boolean) -->
    • th:if, th:unless, th:switch, th:case

      <!-- if (조건이 true일 때) -->
      <div th:if="${user.age >= 18}">
          <p>성인입니다</p>
      </div>
      
      <!-- unless (조건이 false일 때) -->
      <div th:unless="${user.active}">
          <p>비활성 사용자입니다</p>
      </div>
      
      <!-- 빈 값 체크 -->
      <p th:if="${not #strings.isEmpty(user.email)}">
          이메일: [[${user.email}]]
      </p>
      
      <!-- null 체크 -->
      <div th:if="${product != null}">
          <p th:text="${product.name}">상품명</p>
      </div>
      
      <div th:switch="${user.role}">
          <p th:case="'ADMIN'">관리자</p>
          <p th:case="'USER'">일반 사용자</p>
          <p th:case="'GUEST'">게스트</p>
          <p th:case="*">기타</p>  <!-- default -->
      </div>
      
      <!-- 상품 상태 표시 -->
      <span th:switch="${product.status}">
          <span th:case="'AVAILABLE'" class="badge-success">판매중</span>
          <span th:case="'SOLD_OUT'" class="badge-danger">품절</span>
          <span th:case="'DISCONTINUED'" class="badge-warning">단종</span>
      </span>
    • @{…}

      <!-- 기본 URL -->
      <a th:href="@{/users}">사용자 목록</a>
      
      <!-- 경로 변수 -->
      <a th:href="@{/users/{id}(id=${user.id})}">상세보기</a>
      <!-- 결과: /users/123 -->
      
      <!-- 여러 경로 변수 -->
      <a th:href="@{/users/{userId}/orders/{orderId}(userId=${user.id}, orderId=${order.id})}">
          주문 상세
      </a>
      <!-- 결과: /users/123/orders/456 -->
      
      <!-- 쿼리 파라미터 -->
      <a th:href="@{/search(keyword=${keyword}, page=${page})}">검색</a>
      <!-- 결과: /search?keyword=spring&page=1 -->
      
      <!-- 경로 변수 + 쿼리 파라미터 -->
      <a th:href="@{/products/{id}(id=${product.id}, view='detail')}">상품</a>
      <!-- 결과: /products/123?view=detail -->
    Share article
    Contents
    Thymeleaf주요 문법

    LifeLog, DevLog - https://github.com/KYJTHEYJ

    RSS·Powered by Inblog