1. thymeleaf 기본 기능

Uicheon·2024년 1월 18일
0

Spring-mvc2

목록 보기
1/1
post-thumbnail

사전 준비물

  • JAVA 17 이상 설치
  • IDE (intellij etc)

1. 프로젝트 준비

여기에서 스프링 부트 프로젝트를 준비한다.

  • 프로젝트 설정
    • Gralde-Groovy
    • JAVA
    • Spring-boot 3.x
    • JAR
  • Dependencies
    • Spring web
    • Lombok
    • Thymeleaf

스프링 부트 3버전 이상 사용시 주의점
1. JAVA 17이상
2. 패키지 명 javax -> jakarta
3. H2 DB 2.1.214 버전 이상

2. 타임리프 기본기능

타임리프를 사용하려면 다음 선언을 하면 된다.

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

• 간단한 표현:
  ◦ 변수 표현식: ${...}
  ◦ 선택 변수 표현식: *{...}
  ◦ 메시지 표현식: #{...}
  ◦ 링크 URL 표현식: @{...}
  ◦ 조각 표현식: ~{...}
• 리터럴
  ◦ 텍스트: 'one text', 'Another one!',…
  ◦ 숫자: 0, 34, 3.0, 12.3,…
  ◦ 불린: true, false
  ◦ 널: null
  ◦ 리터럴 토큰: one, sometext, main,…
• 문자 연산:
  ◦ 문자 합치기: +
  ◦ 리터럴 대체: |The name is ${name}|
• 산술 연산:
  ◦ Binary operators: +, -, *, /, %
  ◦ Minus sign (unary operator): -
• 불린 연산:
  ◦ Binary operators: and, or
  ◦ Boolean negation (unary operator): !, not
• 비교와 동등:
  ◦ 비교: >, <, >=, <= (gt, lt, ge, le)
  ◦ 동등 연산: ==, != (eq, ne)
• 조건 연산:
  ◦ If-then: (if) ? (then)
  ◦ If-then-else: (if) ? (then) : (else)
  ◦ Default: (value) ?: (defaultvalue)
• 특별한 토큰:
  ◦ No-Operation: _

너무 많은 기능이 있으므로
관리자 페이지 직접 구현 아니라면 이런 기능이 이런 이름으로 있다. 하고 넘어가자.

1. 텍스트 - text, utext

타임리프는 HTML 태그 속성에 기능을 정의 한다.
데이터를 출력(렌더링?) 할 때는 th:text[[...]]를 사용한다.

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

<!-- 태그가 아닌 HTML 컨텐츠에서 직접 출력시 -->
<div class="content">컨텐츠 내용은 [[${data}]] 입니다</div>

가끔 게시판을 이용하다보면 태그 속성을 넘겨받는다. 이를 그대로 출력하면 다음과 같다

@GetMapping("/text-basic")
 public String textBasic(Model model) {
 model.addAttribute("data", "Hello <b>Spring!</b>");
 return "basic/text-basic";
}

// html
[[...]] = Hello <b>Spring</b>

HTML 문서는 <, >과 같은 특수 문자를 기분으로 하기에 <과 같은 문자를 태그의 시작으로 본다. 따라서 <를 태그가 아닌 문자로 표현 할 방법이 필요한다. 이를 HTML 엔티티라고 한다. HTML에서 사용하는 특수 문자를 HTML 엔티티로 변경하는 것을 이스케이프라고한다.

  • < --> &lt;
  • > --> &gt;

Unescape

Thymeleaf에서는 이스케이프를 사용하지 않을 수 있게 -다음 두 방법을 제공한다.

  • th:text --> th:utext
  • [[...]] --> [(...)]

2. 변수 - SpringEL

변수 표현식 : ${...}

- Object
<li><span th:text="${user.username}"></span></li>

- List
<li><span th:text="${users[0].username}"></span></li>

- Map
<li><span th:text="${userMap['userA'].username}"></span></li>

Object

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

List

  • users[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를 찾고 메서드 직접 호출

3. 기본 객체

스프링부트 3부터 사라짐

4. 유틸리티 객체

java.util 객체를 다음과 같이 사용 가능

<!-- temporals는 java 8 util 객체 -->
<span th:text="${#temporals.format(localDateTime, 'yyyy-MM-dd HH:mm:ss')}"></
span>

5. URL 링크

@GetMapping("/link")
public String link(Model model) {
 model.addAttribute("param1", "data1");
 model.addAttribute("param2", "data2");
 return "basic/link";
}
단순 url
<a th:href="@{/hello}"/>

쿼리 파라미터
<a th:href="@{/hello(param1=${param1}, param2=${param2})}"/>

경로 변수 (Path Variables)
<a th:href="@{/hello/{param1}/{param2}(param1=${param1}, param2=${param2})}"/>

경로 + 쿼리 파라미터
<a th:href="@{/hello/{param1}(param1=${param1}, param2=${param2})}"/>

6. 리터럴

리터럴이란 소스 코드 상 고정 된 값

String a = "Hello"
int a = 10 * 20
  • 타임리프 문자 리터럴은 '(작은 따옴표) 감싸야 한다.
  • 공백 없이 쭉 이어진다면 작은 따옴표 생략 가능
    <span th:text="hello">
  • 공백이 있다면 오류
    <span th:text="hello world!"></span>
  • 리터럴 대체
    • 기존: <span th:text="'hello ' + ${data}">
    • 리터럴 대체: <span th:text="|hello ${data}|">

7. 연산

  • 비교연삭
  • 조건식
  • Elvis
  • No-Op

8. 속성 설정/추가

속성 설정
<input type="text" name="mock" th:name="userA" />

속성 추가
th:attrappend : 속성 값의 뒤에 값을 추가한다.
<input type="text" class="text" th:attrappend="class='large'" />
th:attrprepend : 속성 값의 앞에 값을 추가한다.
<input type="text" class="text" th:attrpreppend="class='large'" />
th:classappend : class 속성에 자연스럽게 추가한다
<input type="text" class="text" th:classappend="class='large'" />

checkbox에서 사용 가능한  th:checked="false" 기능 (checked 예약어 우회)
<input type="checkbox" name="active" th:checked="false" />

9. 반복

th:each

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

반복의 두번째 파라미터(Stat)

  • 생략 가능
  • 지정한 변수명(ex: user) + stat
    • ex) userStat
<div th:each="user, userStat : ${users}">
  <span th:text="{userStat.index}"/>
  ...
</div>

반복 상태 유지 기능
index : 0부터 시작하는 값
count : 1부터 시작하는 값
size : 전체 사이즈
even , odd : 홀수, 짝수 여부( boolean )
first , last :처음, 마지막 여부( boolean )
current : 현재 객체

10. 조건부 평가

if, unless(if 반대)

타임리프는 해당 조건이 맞지 않으면 태그 자체를 렌더링하지 않는다.
만약 다음 조건이 false 인 경우 <span>...<span> 부분 자체가 렌더링 되지 않고 사라진다.
<span th:text="'미성년자'" th:if="${user.age lt 20}"></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:each="user : ${users}">
  ...
</th:block>

13. 자바스크립트 인라인

<script th:inline="javascript">

profile
컨셉입니다~

0개의 댓글