본문 바로가기

Spring Boot/thymeleaf

타임리프 기본 표현식

반응형

 

타임리프란?

  1. 타임리프는 SSR(Server Side Render)을 하는 템플릿 엔진으로 백엔드 서버에서 HTML을 동적으로 렌더링 한다.
  2. 순수 HTML을 최대한 유지하기 때문에 html을 서버를 거치지 않고 직접 열어도 내용을 확인할 수 있다(당연히 동적으로 렌더링되지 않음)  => 이처럼 순수 html을 그대로 유지하면서 뷰 템플릿도 사용할 수 있는 특징을 내츄럴 템플릿이라고 함
  3. 스프링의 기능을 편리하게 사용할 수 있다. 
  4. 보통 간단한 화면을 구현할 때 사용된다
  5. html 문서에 선언을 추가하여 사용할 수 있다
<html xmlns:"http://www.thymeleaf.org">

 

타임리프의 기본 표현식

1. 텍스트 출력

타임리프는 기본적으로 html 태그에 th: 로 시작되는 기능을 속성으로 추가하여 사용할 수 있다 

텍스트 출력은 th:text 를 사용한다

 

<span th:text="${data}></span>

 

다음과 같은 경우 서버에서 넘어온 data의 값이 span태그 사이에 출력된다 

 

태그 밖에서 텍스트를 출력하고 싶은 경우 [[...]]를 사용한다

 

[[${data}]]

 

다음과 같은 경우에도 서버에서 넘어온 data값이 출력된다

 

그리고 타임리프는 서버에서 넘어오는 값을 자동으로 escape처리 해준다 

예를들어 <b> 태그를 사용했을 경우 &lt;b&gt; 로 전달된다 

이를 적용시키고 싶지 않은 경우 th:utext 또는 [(....)]를 사용한다

=> 데이터값을 받아와도 태그로 동작하기 때문에 의도하지 않은 상황 발생 가능, 안쓰는게 좋다

 

2. SpringEL 

SpringEL은 Spring express language로 타임리프 내에서 변수를 사용가능하게 해준다

위의 ${data} 처럼 사용한다

 

 User userA = new User("userA", 10);
 User userB = new User("userB", 20);
 
 List<User> list = new ArrayList<>();
 list.add(userA);
 list.add(userB);
 
 Map<String, User> map = new HashMap<>();
 map.put("userA", userA);
 map.put("userB", userB);
 
 
 model.addAttribute("user", userA);
 model.addAttribute("users", list);
 model.addAttribute("userMap", map);

 

다음과 같이 서버에서 model에 값을 넣어서 넘겨준다 (userA의 경우 username과 age를 가진 object임)

 

Object  

${user.username}
${user['username']}
${user.getUsername()}

 

List

${users[0].username}
${users[0]['username']}
${users[0].getUsername()}

 

Map

${userMap['userA'].username}
${userMap['userA']['username']}
${userMap['userA'].getUsername()}

 

지역변수

th:with로 변수 선언하면 선언한 태그 내에서만 사용되는 지역변수가 된다

<div th:with="hello=${data}">
	<p>안녕하세요 <span th:text="${data.username}"></span>입니다</p>
</div>

 

3. 기본 객체

 

${#request} - 스프링 부트 3.0부터 제공하지 않는다.

${#response} - 스프링 부트 3.0부터 제공하지 않는다.

${#session} - 스프링 부트 3.0부터 제공하지 않는다.

${#servletContext} - 스프링 부트 3.0부터 제공하지 않는다.

${#locale}

 

파라미터 정보를 받아오려면 request.getParameter()로 접근해야하기 때문에 더 간단하게 접근할 수 있도록 편의 객체를 제공한다. 

${param.paramData}
${session.sessionData}
${@helloBean.hello('Spring!')}

편의객체를 통해 파라미터 정보, 세션 정보를 쉽게 받아올 수 있고 @를 이용하여 스프링빈에 직접 접근도 가능하다

 

4. 유틸리티 객체

타임리프 공식문서 참고해서 사용하기

https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#expression-utility-objects

 

Tutorial: Using Thymeleaf

1 Introducing Thymeleaf 1.1 What is Thymeleaf? Thymeleaf is a modern server-side Java template engine for both web and standalone environments, capable of processing HTML, XML, JavaScript, CSS and even plain text. The main goal of Thymeleaf is to provide a

www.thymeleaf.org

https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#appendix-b-expression-utility-objects

 

Tutorial: Using Thymeleaf

1 Introducing Thymeleaf 1.1 What is Thymeleaf? Thymeleaf is a modern server-side Java template engine for both web and standalone environments, capable of processing HTML, XML, JavaScript, CSS and even plain text. The main goal of Thymeleaf is to provide a

www.thymeleaf.org

 

공식문서에 명시되지 않은 자바8에서 나온 LocalDate 관련 유틸리티 객체 사용

 

<h1>LocalDateTime</h1>

<ul>
 <li>default = <span th:text="${localDateTime}"></span></li>
 <li>yyyy-MM-dd HH:mm:ss = <span th:text="${#temporals.format(localDateTime,'yyyy-MM-dd HH:mm:ss')}"></span></li>
</ul>

<h1>LocalDateTime - Utils</h1>

<ul>
 <li>${#temporals.day(localDateTime)} = <span th:text="${#temporals.day(localDateTime)}"></span></li>
 <li>${#temporals.month(localDateTime)} = <span th:text="${#temporals.month(localDateTime)}"></span></li>
 <li>${#temporals.monthName(localDateTime)} = <span th:text="${#temporals.monthName(localDateTime)}"></span></li>
 <li>${#temporals.monthNameShort(localDateTime)} = <span th:text="${#temporals.monthNameShort(localDateTime)}"></span></li>
 <li>${#temporals.year(localDateTime)} = <span th:text="${#temporals.year(localDateTime)}"></span></li>
 <li>${#temporals.dayOfWeek(localDateTime)} = <span th:text="${#temporals.dayOfWeek(localDateTime)}"></span></li>
 <li>${#temporals.dayOfWeekName(localDateTime)} = <span th:text="${#temporals.dayOfWeekName(localDateTime)}"></span></li>
 <li>${#temporals.dayOfWeekNameShort(localDateTime)} = <span th:text="${#temporals.dayOfWeekNameShort(localDateTime)}"></span></li>
 <li>${#temporals.hour(localDateTime)} = <span th:text="${#temporals.hour(localDateTime)}"></span></li>
 <li>${#temporals.minute(localDateTime)} = <span th:text="${#temporals.minute(localDateTime)}"></span></li>
 <li>${#temporals.second(localDateTime)} = <span th:text="${#temporals.second(localDateTime)}"></span></li>
 <li>${#temporals.nanosecond(localDateTime)} = <span th:text="${#temporals.nanosecond(localDateTime)}"></span></li>
</ul>

 

 

5. URL 링크

타임리프에서 url생성 시 @{...} 사용

 

<li><a th:href="@{/hello}">basic url</a></li>
<li><a th:href="@{/hello(param1=${param1}, param2=${param2})}">hello query param</a></li>
<li><a th:href="@{/hello/{param1}/{param2}(param1=${param1}, param2=${param2})}">path variable</a></li>
<li><a th:href="@{/hello/{param1}(param1=${param1}, param2=${param2})}">path variable + query parameter</a></li>

 

param1 = data1, param2 = data2 일때

 

@{/hello}

=> /hello

 

@{/hello(param1=${param1},param2=${param2})}

=> /hello?param1=data1&param2=data2 

경로 뒤 () 부분이 파라미터로 처리됨

 

@{/hello/{param1}/{param2}(param1=${param1}, param2=${param2})}

=> /hello/data1/data2

경로에 변수가 있으면 () 부분이 경로 변수로 처리됨

 

@{/hello/{param1}(param1=${param1}, param2=${param2})}

=> /hello/data1?param2=data2

경로에 있는 변수는 경로 변수로 처리되고 나머지는 쿼리파라미터로 처리됨

 

 

6. 리터럴

소스 코드상에 고정된 값 

상수과 헷갈렸었는데 상수와 다름 

리터럴은 진짜 말 그대로 값 자체이고 상수는 리터럴을 이용해서 초기화시킨 변하지 않는 값임

 

리터럴의 경우 무조건 ' ' 로 감싸주어야 하지만 공백이 없는 경우 그냥 써도 리터럴로 인식됨

공백이 포함된 경우 ' '로 감싸주어야 함 

변수를 포함할 경우 'hello' + ${data} 와 같이 사용하거나, 리터럴 대체를 사용할 수 있음

리터럴 대체의 경우 |...|의 형식으로  

|hello ${data}| 처럼 사용하면 하나의 리터럴로 인식됨

 

 

7. 연산

th:text 에 포함시 계산된 후 출력됨

 

<li>1 > 10 = <span th:text="1 > 10"></span></li>
<li>1 > 10 = <span th:text="1 gt 10"></span></li>
<li>1 > 10 = <span th:text="1 &gt; 10"></span></li>

셋 다 동일한 비교연산

비교 연산 시 불리언으로 출력. html 엔티티를 사용할 수도 있음

( > (gt), < (lt), >= (ge), <= (le), ! (not), == (eq), != (neq, ne)) <- SpEL을 지원하기 때문에 &;를 붙이지 않고도 사용가능

 

<li>(10 % 2 == 0)? '짝수':'홀수' = <span th:text="(10 % 2 == 0)? '짝수':'홀수'"></span></li>

조건식 

자바의 조건식과 유사함 10%2 == 0이 true면 짝수, false면 홀수 출력

 

<li>${data}?: '데이터가 없습니다.' = <span th:text="${data}?: '데이터가 없습니다.'"></span></li>
<li>${nullData}?: '데이터가 없습니다.' = <span th:text="${nullData}?: '데이터가 없습니다.'"></span></li>

Elvis 연산자 ?: 

? 앞의 값이 null이 아닐 시 값만 출력함

? 앞이 null이면 Elvis연산자의 뒷 부분을 출력함

 

<li>${data}?: _ = <span th:text="${data}?: _">데이터가 없습니다.</span></li>
<li>${nullData}?: _ = <span th:text="${nullData}?: _">데이터가 없습니다.</span></li>

No-operation ?:_

? 앞의 값이 null이 아닐시 값만 출력함

null이면 th:text무시하고 원래대로 동작함

 

 

8. 속성

기본적으로는 속성앞에 th: 를 붙여서 지정할 경우 서버에서 렌더링이 될 때 기존속성을 대체하거나 없는 경우 생성한다

 

다음 방법은 기존 속성을 대체하지 않고 기존 값에 값을 추가해 준다

th:attrappend = "class=' large'" 

=> class 속성 뒤에 ' large'를 붙인다
th:attrprepend = "class='large '"

=> class 속성 뒤에 'large '를 붙인다
th:classappend = "large"

=> class 속성 뒤에 붙인다. 띄어쓰기 안해줘도 알아서 띄어서 붙여준다

 

checkbox type의 경우 checked 속성이 포함 되어있기만 하면 체크되기에 불편하다

=> th:checked 를 이용해 true면 값포함 , false면 checked속성을 넣지 않음으로 체크 설정이 가능하다

 

 

9. 반복

자바의 for(String item : list){ } 와 비슷하게 th:each를 사용할 수 있다

 

<tr th:each="user : ${users}">
    <td th:text="${user.username}">username</td>
    <td th:text="${user.age}">0</td>
</tr>

${users} 순서대로 처음부터 끝까지 반복

userStat 이용시 다양한 정보 얻을 수 있음

userStat.index: 0부터 시작

userStat.count: 1부터 시작

userStat.size: 전체 사이즈

userStat.even, userStat.odd: 홀수 짝수 여부

userStat.first, userStat.last: 처음, 마지막 여부

userStat.current: 현재 객체

 

 

10. 조건부 평가

th:if , th:unless를 사용한다

조건이 맞지 않으면 조건문이 들어간 태그를 렌더링하지 않는다 

th:case 의 경우 다음과 같이 사용한다

<span th:case="10">10살</span>
<span th:case="20">20살</span>
<span th:case="*">기타</span>

 

 

11. 주석

표준 html 주석

<!--
<span th:text="${data}">html data</span>
-->

타임리프가 렌더링하지 않는다

서버없이 열었을 때도 주석으로 동작한다

 

 

타임리프 파서 주석

<!--/* [[${data}]] */-->

<!--/*-->
<span th:text="${data}">html data</span>
<!--*/-->

타임리프의 주석이다 렌더링할때 주석부분을 없애서 전달한다

두번째 주석의 경우 서버 없이 열었을 때는 보인다

 

 

타임리프 프로토타입 주석

<!--/*/
<span th:text="${data}">html data</span>
/*/-->

html주석으로 처리되기 때문에 파일로 열었을때는 보이지 않지만 타임리프 렌더링을 거치면 보이게 된다

 

 

12. 블록

<th:block> </th:block>으로 사용한다 

th: 태그를 html태그에 넣어서 사용하기 애매한 경우에 사용한다

 

 

참고한 강의

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2/

반응형