우와한 개발자

[ Thymeleaf ] 기본 문법(1) - 텍스트 출력, 속성 바인딩, 조건부 렌더링, 반복문, CSS 제어

by 우와한개발자

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

 

1. 텍스트 출력

1) th:text

  • 태그 안의 기존 텍스트를 통째로 치환
  • HTML 특수문자(<, >, & 등)를 자동으로 이스케이프 처리
  • th:text 대신 인라인 표현식 [[ ]]으로도 사용 가능
<p th:text="${user.name}">기본값</p> # 기본값 → user.name 치환 
<p>[[${user.name}]]</p>

 

2) th:utext

  • HTML 태그가 포함된 텍스트를 이스케이프 없이 그대로 출력
  • 이스케이프를 하지 않으므로 XSS 공격에 주의해서 사용
  • th:utext 대신 인라인 표현식 [( )]으로도 사용 가능
<!-- model에서 "안녕하세요 <b>홍길동</b>" 을 전달했을 때 -->

<!-- th:text → 태그가 문자로 그대로 출력됨 -->
<p th:text="${msg}"></p>
<!-- 결과: 안녕하세요 &lt;b&gt;홍길동&lt;/b&gt; -->

<!-- th:utext → 태그가 실제 HTML로 렌더링됨 -->
<p th:utext="${msg}"></p>
<!-- 결과: 안녕하세요 홍길동(굵게) -->

<p>[(${msg})]</p>

 

2. 속성 바인딩

1) th:value

  • <input> 등의 value 속성에 서버 값을 바인딩
<input type="text" th:value="${user.name}" />

 

2) th:href

  • <a> 태그의 href 속성에 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 -->

 

3) th:src

  • <img>, <script> 등의 src 속성에 동적으로 값을 바인딩
<img th:src="@{/images/{fileName}(fileName=${user.profileImg})}" />
<script th:src="@{/js/app.js}"></script>

 

4) th:action

  • <form> 태그의 action 속성에 URL을 바인딩
<form th:action="@{/user/save}" method="post">

<form th:action="@{/user/{id}(id=${user.id})}" method="post">

 

5) th:attr

  • 특정 속성 전용 문법이 없을 때 임의의 속성을 동적으로 설정
<button th:attr="data-id=${user.id}">삭제</button>
<!-- 결과: <button data-id="1">삭제</button> -->

<!-- 여러 속성 동시에 설정 -->
<button th:attr="data-id=${user.id}, data-name=${user.name}">수정</button>

 

3. 조건부 렌더링

1) th:if / th:unless

  • th:if : 조건이 true일 때 요소를 렌더링
  • th:unless : 조건이 false일 때 요소를 렌더링 (th:if의 반대)
  • 조건이 맞지 않으면 해당 태그 자체가 HTML에서 제거됨
<p th:if="${user.isAdmin}">관리자입니다.</p>
<p th:unless="${user.isAdmin}">일반 사용자입니다.</p>

2) th:switch / th:case

  • Java의 switch문과 동일한 역할
  • th:case="*"는 default에 해당
<div th:switch="${user.role}">
    <p th:case="'ADMIN'">관리자</p>
    <p th:case="'USER'">일반 사용자</p>
    <p th:case="*">알 수 없음</p>
</div>

 

4. 반복문

1) th:each

  • 컬렉션을 순회하면서 HTML 요소를 반복 생성
  • 두 번째 변수(iterStat)로 반복 상태 정보를 얻을 수 있음 (생략 가능)
<tr th:each="user : ${userList}">
    <td th:text="${user.id}"></td>
    <td th:text="${user.name}"></td>
</tr>

 

2) 반복 상태 변수 (iterStat)

속성 타입 의미
index int 0부터 시작하는 인덱스
count int 1부터 시작하는 순번
size int 전체 요소 수
first boolean 첫 번째 요소 여부
last boolean 마지막 요소 여부
even boolean 짝수 번째 여부 (count 기준)
odd boolean 홀수 번째 여부 (count 기준)
<tr th:each="user, iterStat : ${userList}"
    th:classappend="${iterStat.odd} ? 'odd-row' : 'even-row'">
    <td th:text="${iterStat.count}"></td>
    <td th:text="${user.name}"></td>
    <td th:text="${iterStat.last} ? '마지막' : ''"></td>
</tr>

 

5. CSS / 스타일 제어

1) th:class

  • 기존 class 속성을 통째로 동적으로 설정
<p th:class="${isActive} ? 'active' : 'inactive'">상태</p>

 

2) th:classappend

  • 기존 class를 유지하면서 조건에 따라 클래스를 추가
<p class="btn" th:classappend="${isActive} ? ' active'">버튼</p>
<!-- 결과: class="btn active" 또는 class="btn" -->

 

3) th:style

  • style 속성을 동적으로 설정
<p th:style="'color:' + ${fontColor} + '; font-size:16px;'">텍스트</p>

블로그의 정보

우와한개발자 님의 블로그

우와한개발자

활동하기