[Spring boot] Thymeleaf(타임리프)

예림·2024년 6월 10일
2

Spring boot

목록 보기
7/8

템플릿 엔진 중 서버 사이드 템플릿 엔진에 해당하는 Thymeleaf에 대해 알아보자.

Thymeleaf 문법

대부분의 html 속성을  th:xxx 로 변경할 수 있다.

ex: th:text="${변수명}"

  • 표현식
    ◦ 변수 표현식: ${...}
    ◦ 선택 변수 표현식: *{...}
    ◦ 메시지 표현식: #{...}
    ◦ 링크 URL 표현식: @{...}
    ◦ 조각 표현식: ~{...}

  • 리터럴
    ◦ 텍스트: 'one text', 'Another one!',…
    ◦ 숫자: 0, 34, 3.0, 12.3,…
    ◦ 불린: true, false
    ◦ 널: null
    ◦ 리터럴 토큰: one, sometext, main,…

  • text opeation
    ◦ 문자열 연결 : +
    ◦ 문자 대체 : |The name is ${name}|

  • 연산
    ◦ Binary : +, -, *, /, %
    ◦ 마이너스 : -

  • boolean 연산
    ◦ Binary : and, or
    ◦ 부정 : !, not

  • 비교 연산
    ◦ 비교연산자 : >, <, >=, <= (gt, lt, ge, le)
    ◦ 균등연산자 : ==, != (eq, ne)

  • 조건 연산
    ◦ if-then : (if) ? (then)
    ◦ if-then-else : (if) ? (then) : (else)
    ◦ Default : (value) ?: (defaultValue)

text, utext

타임리프의 가장 기본기능인 텍스트를 출력하는 기능

타임리프는 기본적으로 HTML태그의 속성에 기능을 정의해서 동작한다.
HTML의 콘텐츠에 데이터를 출력할 때는 다음과 같이 th:text를 사용한다.

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

HTML 콘텐츠 영역 안에 직접 데이터를 출력할 때는 [[...]]를 사용한다.

[[${data}]]

Escape

HTML 문서는 <,> 같은 특수 문자를 기반으로 정의된다. 따라서 뷰 템플릿으로 HTML 화면을 생성할 때는 출력하는 데이터에 이러한 특수 문자가 있는 것을 주의해서 사용해야 한다.

예를들어

"Hello <b>Spring!</b>"

Spring을 강조하고 싶어서 태그를 추가하면 화면에서 속성이 적용되는 것이 아니라 태그가 포함된 문자열이 그대로 출력된다. 소스 보기를 하면

Hello &lt;b&gt;Spring!&lt;/b&gt;

< 부분이 &lt; 로 변경된 것을 확인할 수 있다.

HTML 엔티티

웹브라우저는 <를 HTML 태그의 시작으로 인식하므로, 이를 문자로 표현할 수 있는 방법이 필요한데, 이것을 HTML 엔티티라고 한다.

< -> &lt;
> -> &gt;
이 외에도 수많은 HTML 엔티티가 있다.

Unescape

그럼 이스케이프 기능을 사용하지 않으려면 어떻게 해야할까?

타임리프는 다음 두 기능을 제공한다.
th:text -> th:utext
[[...]] -> [(...)]

<h1>text vs utext</h1>
 <ul>
    <li>th:text = <span th:text="${data}"></span></li>
    <li>th:utext = <span th:utext="${data}"></span></li>
 </ul>
 <h1><span th:inline="none">[[...]] vs [(...)]</span></h1>
 <ul>
    <li><span th:inline="none">[[...]] = </span>[[${data}]]</li>
    <li><span th:inline="none">[(...)] = </span>[(${data})]</li>
 </ul>

th:inline="none" : 타임리프는 [[...]]를 해석하기 때문에, 화면에 [[...]] 글자를 보여줄 수 없다. 이 태그 안에서는 타임리프가 해석하지 말라는 옵션이다.

이 옵션을 추가하면 Hello <b>Spring!</b>을 출력했을 때 웹 브라우저에서 의도된 대로 수행된다.

Hello Spring!

하지만 실제 서비스를 개발할 때 escape를 사용하지 않아서 HTML이 정상 렌더링 되지 않는 문제가 발생하기도 한다. 따라서 escape를 기본으로 사용하되, 꼭 필요한 때에만 unescape를 사용하는 것이 좋다.

SpringEL

: 스프링이 제공하는 변수 표현식

<ul>Object
   <li>${user.username} =    <span th:text="${user.username}"></span></li>
   <li>${user['username']} = <span th:text="${user['username']}"></span></li>
   <li>${user.getUsername()} = <span th:text="${user.getUsername()}"></span></li>
</ul>
<ul>List
   <li>${users[0].username}    = <span th:text="${users[0].username}"></span></li>
   <li>${users[0]['username']} = <span th:text="${users[0]['username']}"></span></li>
   <li>${users[0].getUsername()} = <span th:text="${users[0].getUsername()}"></span></li>
</ul>
<ul>Map
   <li>${userMap['userA'].username} =  <span th:text="${userMap['userA'].username}"></span></li>
   <li>${userMap['userA']['username']} = <span th:text="${userMap['userA']['username']}"></span></li>
   <li>${userMap['userA'].getUsername()} = <span th:text="${userMap['userA'].getUsername()}"></span></li>

Object

  • user.username : user의 username을 프로퍼티 접근 -> user.getUsername()
  • user['username'] : 위와 같음 -> user.getUsername()
  • user.getUsername() : user의 getUsername()을 직접 호출

List

  • user[0].username : List에서 첫 번째 회원을 찾고 username 프로퍼티 접근 -> list.get(0).getUsername()
  • users[0]['username'] : 위와 같음
  • users[0].getUsername() : List에서 첫 번째 회원을 찾고 메서드 직접 호출

Map

  • userMap['userA'].username : Map에서 userA를 찾고, username 프로퍼티 접근 -> map.get("userA").getUsername()
  • userMap['userA']['username'] : 위와 같음
  • userMap['userA'].getUsername() : Map에서 userA를 찾고 메서드 직접 호출

지역 변수 선언

th:with를 사용하면 지역 변수를 선언할 수 있으며 지역 변수는 선언한 태그 안에서만 사용할 수 있다.

 <div th:with="first=${users[0]}">
    <p>처음 사람의 이름은 <span th:text="${first.username}"></span></p>
 </div>

기본 객체들

  • ${#request} - 스프링부트 3.0부터 제공 X
  • ${#response} - 스프링부트 3.0부터 제공 X
  • ${#session} - 스프링부트 3.0부터 제공 X
  • ${#servletContext} - 스프링부트 3.0부터 제공 X
  • ${#locale}

스프링 부트 3.0에서 위의 객체를 사용하려면 직접 model에 해당 객체를 추가해서 사용해야 한다.

참고자료

profile
백엔드 개발하는 사람

0개의 댓글