FireDrago

[Thymeleaf] 타임리프 기본기능 정리 본문

프로그래밍/템플릿 엔진(thymeleaf, jsp)

[Thymeleaf] 타임리프 기본기능 정리

화이용 2024. 2. 5. 11:40

타임리프는 템플릿 엔진중 하나로 세가지 특징을 가진다.

1. 서버사이드 렌더링 (SSR)

 - 서버단에서 html 파일을 렌더링하여 클라이언트에게 전달한다. 클라이언트단에서 렌더링 (CSR) 하는 React 등과

구분되는 특징이다. JSP 역시 서버사이드 렌더링을 한다.

 

2. 네츄럴 템플릿

- 타임리프는 html을 최대한 유지한다. 타임리프는 JSP와 달리 html 파일로 실행해도 동작한다.

물론 렌더링은 되지 않지만 마크업이 어떻게 표시되는지 확인 할 수 있어 편리하다.

 

3. 스프링과 통합

- 스프링과 통합되어 작동되는 기능들이 많다. JSP보다 타임리프가 더 선호되는 이유이다. 

심지어 JSP는 jar 파일로 배포할 경우 실행되지 않는다. 스프링이 공식적인 지원을 하지 않기 때문이다.

 

<html lang="en" xmlns:th="http://www.thymeleaf.org">

타임리프를 사용하기 위해서는 먼저 xmlns (xml 네임스페이스)를 설정해줘야 한다. 

타임리프 기본 표현식이다. 타임리프를 모두 공부하고, 복습할때 참고하면 이해가 잘 될것이다.

종류 상세
표현식 변수표현식 : ${...}
선택 변수 표현식: *{...}
메시지 표현식: #{...}
링크 URL 표현식: @{...}
조각 표현식: ~{...}
리터릴 텍스트: 'one text', 'Another one!'
숫자: 0, 23, 3.0, ...
불린: true, false
널: null
리터럴 토큰: one, sometext, main, ...
문자 연산 문자 합치기 : +
리터럴 대체 : |The name is ${name}|
산술 연산 이진 연산 : +, -, *, /, %  
 - 두개의 값 필요
부호 연산 : -
 - 단일 값 
불린 연산 and, or

 

1. 타임리프 기능

<텍스트 표시>

종류 방법 예시
태그 속성 th:text="${data}"
직접입력 [[${data}]]
태그 속성
(unescape)
th:utext="${data}" "Hello <b>Spring!</b>" 문자열을 타임리프에 보냈을때,
직접입력
(unescape)
[(${data})]

타임리프에서는 '이스케이프' 기능이 자동으로 적용된다.

즉 html 에서 사용되는 특수기호들을 입력해도 문자열로 인식하고 표시해준다.

이스케이프 기능을 사용하고 싶지 않을때는 텍스트 표시방법을 다르게 표현해야 한다.

 

<변수 표현식>

종류 방법 예시
${data} :
EL태그 사용

객체 (Object) <span th:text="${user.username}">
<span th:text="${user['username']}">
<span th:text="${user.getUsername()}">
리스트 (List) <span th:text="${users[0].username}">
<span th:text="${users[0]['username']}">
<span th:text="${users[0].getUsername()}">
맵 (Map) <span th:text="${userMap['userA'].username}">
<span th:text="${userMap['userA']['username']}">
<span th:text="${userMap['userA'].getUsername()}">
지역변수 사용 var = ${data} <div th:with="first=${users[0]}">
    <span th:text="${first.username}"></span>
</div>

Spring El 은 크게 세가지 표현 방법이 있다.

List, Map 같은 컬렉션이 전달된 경우에도 각각의 방법으로 객체를 꺼내온뒤 똑같은 방식으로 표현할 수 있다.

1. 객체.프로퍼티 (${user.username})

2. 객체['프로퍼티'] (${user['username']})

3. 객체.getter() (${user.getUsername()})

 

지역변수를 선언하기 위해 th:with="" 구문을 사용할 수 있다. 선언된 지역변수는 해당 태그 내부에서만 사용할 수 있다.

 

<기본 객체>

종류 방법 예시
Session ${session.세션키} session = <span th:text="${session.sessionData}"/>
Model ${모델키} request = <span th:text="${request}"/>
파라미터 ${param.파라미터명} Request Parameter = <span th:text="${param.paramData}"/>
스프링빈 ${@빈이름.메서드명(매개변수)} spring bean = <span th:text="${@helloBean.hello('Spring!')}"/>

타임리프는 몇가지 객체에 대하여 바로 접근 할 수 있는 기능을 제공한다.

파라미터의 경우, 컨트롤러에서 Model에 담아서 전달하지 않더라도 html 에서 사용할 수 있다.

 

<URL 링크>

종류 예시
쿼리파라미터 <a th:href="@{/hello(param1=${param1}, param2=${param2})}"/>
- /hello?param1=data1,param2=data2
- ( ) 부분은 파라미터 처리된다. 
경로 변수 @{/hello/{param1}/{param2}(param1=${param1}, param2=${param2})}
- /hello/data1/data2
- URL 경로상에 { } 부분은 경로 변수로 처리된다.
쿼리파라미터+
경로변수
@{/hello/{param1}(param1=${param1}, param2=${param2})}
- 둘을 함께 사용하는 것도 가능하다.

 

<연산>

종류 방법 예시
비교연산 >(gt), <(lt), >=(ge),
<=(le), !(not), ==(eq)
 <span th:text="1 >= 10">
- false 표시된다.
조건식 조건식? '참' : '거짓' <span th:text="(10 % 2 == 0)? '짝수':'홀수'"/>
Elvis 연산자 ${변수명}?: '거짓' <h1 th:text="${name ?: 'Guest'}"/>
  -> name 이 null이면 'Guest'

<p th:text="${list?.get(0)}"/>
  -> list가 null이 아니면 get(0) 메서드 실행
No-Operation ${변수명}?:_  <span th:text="${nullData}?: _">데이터가 없습니다.</span>
- nullData 가 없으면 '데이터가 없습니다.' 표시 

 

<속성값 처리>

종류 방법 예시
속성 설정 th:* <input type="text" name="mock" th:name="userA" />
속성 추가 th:attrappend  <input type="text" class="text" th:attrappend ="class='large '" />
- 'textlarge' 뒤에 속성 추가
th:attrprepend <input type="text" class="text" th:attrprepend="class='large '" />
- 'largetext' 앞에 속성 추가
th:classappend <input type="text" class="text" th:classappend="class='large '" />
- 'text large' 띄어쓰기 구분
체크 처리 th:checked="false/true"  <input type="checkbox" name="active" th:checked="false" />
<input type="checkbox" name="active" th:checked="${data}" />

HTML 은 checked 속성만 있으면 무조건 체크표시한다. 하지만 th:checked 를 사용하면

th:checked="false" 를 사용하여 체크 표시를 해제할 수 있다. 

 

<리터럴>

종류 방법 예시
리터럴 대체 | | <span th:text="'hello ' + ${data}">  
<span th:text="|hello ${data}|"> 

타임리프에서 문자열은 ' ' 사이에 입력한다. 실수 잦은 부분이니 주의하자

 

<반복>

종류 예시
반복문 <tr th:each="user : ${users}">
        <td th:text="${user.username}">username</td>
        <td th:text="${user.age}">0</td>
</tr>
반복 상태유지 <tr th:each="user, userStat : ${users}">
        <td th:text="${userStat.count}">username</td>
        <td th:text="${user.username}">username</td>
        <td th:text="${user.age}">0</td>
</tr>
index : 0부터 시작하는 값    ex)) ${userStat.index}
count : 1부터 시작하는 값
size : 전체 사이즈
even , odd : 홀수, 짝수 여부( boolean )
first , last :처음, 마지막 여부( boolean )
current : 현재 객체

반복문 상태유지 구문은 두번째 변수명을 지정할때 지정할 수 있다. 

생략할 수 도 있는데 그때는 첫번째 파라미터 + "Stat" 으로 사용할 수 있다.

 

<조건문>

종류 방법 예시
if 문 th:if="조건식" <span th:text="미성년자" th:if="${user.age lt 20}">0</span>
unless 문 th:unless="조건식" <span th:text="미성년자" th:unless="${user.age ge 20}"></span>
switch 문 th:switch="값"
   th:case="조건식"
<td th:switch="${user.age}">
    <span th:case="10">10살</span>
    <span th:case="20">20살</span>
    <span th:case="*">기타</span>

조건문을 사용할때 조건식이 false인 경우 타임리프는 태그 자체를 없앤다.

즉 조건에 만족되지 않는 태그는 화면에 출력되지 않는다.

 

<주석>

종류 설명 예시
HTML 주석 타임리프가 렌더링 하지 않고, 
그대로 남겨둔다.
<!--
<span th:text="${data}">html data</span>
-->
타임리프 파서 주석 타임리프의 진짜 주석이다. 
렌더링에서 주석 부분을 제거한다.
<!--/* 
[[${data}]] 
*/-->
타임리프 프로토타입 주석  HTML 파일을 그대로 열어보면 
주석처리가 되지만, 타임리프를 
렌더링 한 경우에만 보인다.
<!--/*/
<span th:text="${data}">html data</span>
/*/-->

 

<블록>

종류 사용법 예시
블록태그 th:block <th:block th:each="user : ${users}">
     <div>
         사용자 이름 <span th:text="${user.username}"></span>
     </div>
     <div>
         요약 <span th:text="${user.username} + ' / ' + ${user.age}"></span>
     </div>
</th:block>

블록을 지정해줌으로서 지역변수를 두개의 태그에 걸쳐 사용할 수 있게 되었다.

위 예처럼 태그안의 속성을 사용하기 애매한 경우 블록으로 묶어서 사용하면 된다.