월루를 꿈꾸는 대학생
[MVC-2] 타임리프 본문
메뉴얼
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html
타임리프 특징
- 서버 사이드 html 랜더링 ssr
- 네츄럴 템플릿
- 스프링 통합 지원
서버사이드 html 랜더링
- 타임리프는 백엔드 서버에서 html 동적으로 랜더링
네츄럴 템플릿
- html 파일을 순수하게 유지하려고 함 = 파일만 열어도 안 깨짐
- 서버를 통해 뷰 템플릿을 동적으로 변경하고 값을 덮어씌워서 랜더링함
순수 html을 유지하면서 뷰 템플릿도 사용할 수 있는 것을 네츄럴 템플릿이라고 한다
스프링 통합 지원
- 스프링과 통합이 아주 잘 되어 있음
타임리프 기본 기능
타임리프 선언
<html xmlns:th="http://www.thymeleaf.org">
기본 표현식
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#standard-expression-syntax
텍스트
- th:text
- text 태그를 사용해도 되고 , 그냥 영역 안에 [[ ... ]] 넣으면 인식해서 쓰기 가능
<span th:text="${data}">
<ul>
<li>th:text 사용 <span th:text="${data}"></span></li>
<li>컨텐츠 안에서 직접 출력하기 = [[${data}]]</li>
</ul>
ESCAPE
- html은 < , > 같은 특문 기준 정의
- 저기 컨트롤러에서 <\b> Spring <\b> 이렇게 문자열로 모델 세팅해도 html 받으면 저 태그가 다르게 바뀜
- 소스코드 보면 < 이게 < 이래됨
HTML 엔티티
- html은 < 요걸 태그의 시작으로 인식함 그래서 이걸 문자로 인식할 표현이 필요함 = html엔티티
- html에서 특수문자를 html엔티티로 변경하는 것 = 이스케이프
- [[\ ]] 요거 쓰면 기본적인 이스케이프 제공해줌
->즉 그냥 문자인식으로 바꿔주는 건데 지금 bold 하고 싶으니까 unescape 해야함
UNESCAPE
- th:text -> th:utext
- [[...]] -> [(...)]
<li><span th:inline="none">[[...]] = </span>[[${data}]]</li>
<li><span th:inline="none">[(...)] = </span>[(${data})]</li>
<li>th:text = <span th:text="${data}"></span></li>
<li>th:utext = <span th:utext="${data}"></span></li>
이스케이프를 디폴트로 쓰자 -> 정상 랜더링 안 되는 많은 문제가 야기될 수 있으니 이스케이프가 필요함
변수 - 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>
</ul>
user.username : user의 username을 프로퍼티 접근 user.getUsername()
user['username'] : 위와 같음 user.getUsername()
user.getUsername() : user의 getUsername() 을 직접 호출
지역 변수 선언
- th:with 를 사용해서 지역변수 선언 가능 해당 변수는 태그 안에서만 사용 가능함
<div th:with="first=${users[0]}"> <p>처음 사람의 이름은 <span th:text="${first.username}"></span></p> </div>
기본 객체들
- 기본객체가 3.0 기준으로 좀 바뀜
- 3.0 이상이면 기본객체는 거의 없고 그냥 model에서 넘기는 편이 좋음
유틸리티 객체와 날짜
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>
리터럴
- 소스코드 상 고정된 값
- 문자: 'hello' : 무조건 작은 따옴표 감싸야함
- 숫자: 10
- 불린: true , false
- null: null
리터럴 대체(Literal substitutions)
<span th:text="|hello ${data}|">
- || 로 감싸는게 가장 편한듯
연산
비교 연산
(gt), < (lt), >= (ge), <= (le), ! (not), == (eq), != (neq, ne)
<li>1 > 10 = <span th:text="1 > 10"></span></li> <li>1 gt 10 = <span th:text="1 gt 10"></span></li> <li>1 >= 10 = <span th:text="1 >= 10"></span></li> <li>1 ge 10 = <span th:text="1 ge 10"></span></li> <li>1 == 10 = <span th:text="1 == 10"></span></li> <li>1 != 10 = <span th:text="1 != 10"></span></li>
조건식
<li>(10 % 2 == 0)? '짝수':'홀수' = <span th:text="(10 % 2 == 0)? '짝수':'홀수'"></span></li>
Elvis 연산자 : 조건식 편의 버전
- No-Operation: _ 인 경우 타임리프 실행되지 않는 것처럼 동작
<li>${data}?: _ = <span th:text="${data}?: _">데이터가 없습니다.</ span></li> <li>${nullData}?: _ = <span th:text="${nullData}?: _">데이터가 없습니다.</span></li>
속성값 설정
타임리프 태그 속성
- th : ~~
- 기존 속성을 대체
```html - th:attrappend =
- th:attrprepend =
- th:classappend = <input type="text" class="text" th:classappend="large" /
check
타임리프의 th:checked 는 값이 false 인 경우 checked 속성 자체를 제거한다.
타임리프 렌더링 후:
반복
- th:each
<tr th:each="user : ${users}"> <td th:text="${user.username}">username</td> <td th:text="${user.age}">0</td> </tr>
조건부 평가
- if / unless
주석
블록
<th:block>
- div 2개나 for each로 해결하기 어려운 경우 넣어서 씀
자바스크립트 인라인
- 타임리프 내에서 자바스크립 사용할 수 있도록 기능을 제공
<script th:inline="javascript">
var username = [[${user.username}]];
- 인라인 사용 전 var username = userA;
- 인라인 사용 후 var username = "userA"; 인라인 사용 후 문자타입이면 "" 추가 됨
자바스크립트 내추럴 템플릿
html 파일 열어도 동작
var username2 = /[[${user.username}]]/ "test username";
- 인라인 사용 전 var username2 = /userA/ "test username"; : 그대로 해석
- 인라인 사용 후 var username2 = "userA"; : 주석제거 하고 userA가 처리 됨
var user = [[${user}]];
- 인라인 사용 전 var user = BasicController.User(username=userA, age=10);
- 인라인 사용 후 var user = {"username":"userA","age":10}; : 인라인 사용 후 객체를 json 형태로 변경
템플릿 조각
- th:fragment 로 코드조각 표시
https://maenco.tistory.com/entry/Thymeleaf-Templates-Fragments-%ED%85%9C%ED%94%8C%EB%A6%BF-%EC%A1%B0%EA%B0%81
템플릿 레이아웃
코드조각을 레이아웃에 넘겨서 사용
head를 공통으로 쓰고 싶은 경우 공통 정보를 모아두고 필요한 부분만 추가적으로 추가해서 사용
common_header({::title},{::link}) 이 부분이 핵심
::title 은 현재 페이지의 title 태그들을 전달
::link 는 현재 페이지의 link 태그들을 전달
head뿐만 아니라 html 전체에도 적용가능
html 에 th:fragment 속성을 정의하고 해당 레이아웃 파일을 기본으로 하고 여기에 필요한 내용을 전달해서 부분부분 변경하면 됨
'Programing > Spring Boot' 카테고리의 다른 글
[MVC-1] 스프링 MVC -웹 페이지 (0) | 2023.08.08 |
---|---|
[MVC-1] 스프링 MVC - 기본 기능 (0) | 2023.08.01 |
[MVC-1] 스프링 MVC - 구조 이해 (0) | 2023.08.01 |
[MVC-1] MVC 프레임 워크 만들기 (0) | 2023.08.01 |
[MVC-1] 서블릿 , JSP , MVC패턴 (0) | 2023.07.25 |