타임리프 속성(th:)에 삼항연산자 (조건식 ? 참인 경우 : 거짓인 경우)
controller 값 세팅
@GetMapping("ex4")
public String ex4(Model model) {
Student std = new Student("67890", "잠만보", 22);
model.addAttribute("std", std);
return "example/ex4";
}
html
<h4 th:text="${std.age == 30} ? '서른' : '서른아님'">삼항연산자</h4>
출력 화면

[작성법]
값 ?: 값이 없을 때
삼항 연산자에서 조건식 자리에 값(변수명)만 작성
(==, != 등의 연산자 사용 X)
우변에는 값이 없을 때에 대한 값만 작성
조건식값이 존재하면 해당 값을 출력
없으면 우변을 출력
-> 해당 값이 있는지 없는지에 따라 동작하는 연산자
html
<p th:text="${member} ?: '회원 데이터 없음'"></p>
<p th:text="${std} ?: '학생 데이터 없음'"></p>
출력 화면

조건식의 값이 없을 경우 (== null)
타임리프 코드를 해석하지 않는 연산자
타임리프 코드 해석 X
-> 일반 HTML 태그로 동작
-> HTML 태그 사이 내용(content)이 화면에 출력
html
<!-- 회원 데이터 없음 -->
<p th:text="${member} ?: _">회원 데이터 없음</p>
<!-- std.toString() 결과 출력 -->
<p th:text="${std} ?: _">학생 데이터 없음</p>
JavaScript 속성
script 태그에 작성하는 속성
타임리프 문법으로 출력된 내용/값을 JS에 알맞은 타입으로 변환
controller 값 세팅
@GetMapping("ex5")
public String ex5(Model model) {
// Model : Spring 에서 값 전달 역할을 하는 객체
// 기본적으로 request scope + session 으로 확장 가능
model.addAttribute("message", "타임리프 + JavaScript 사용 연습");
model.addAttribute("num1", 12345);
return "example/ex5";
}
<h3 id="message"></h3>
<h3 id="num1"></h3>
<script th:inline="javascript">
// JS Inline - Natural Template
// 스크립트 태그 내부에서 타임리프의 변수나 연산을 사용할 수 있게함
// - HTML 파일 독립 실행 시
// JS 내부 타임리프 코드 오류를 발생하지 않게함
// + HTML 문법 오류 (컴파일 오류)도 해결
const message = /*[[${message}]]*/ "message값";
const num1 = /*[[${num1}]]*/ 100;
document.querySelector("#message").innerText = message;
document.querySelector("#num1").innerText = num1;
</script>
요소에 class 속성 값을 동적으로 추가
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>타임리프 예제 5</title>
<style>
.red {color:red;}
.green {color:green;}
.deco {text-decoration: underline;}
</style>
</head>
<body>
<h3>th:classappend 속성 : 요소에 class 속성 값을 동적으로 추가</h3>
<h4 th:classappend="red">th:classappend 테스트 중</h4>
<h4 class="red" th:classappend="deco">th:classappend 테스트 중</h4>
<!-- lt : <
gt : > -->
<!-- num1 이 10000보다 클 경우 green 아니면 red -->
<h4 th:classappend="${num1 gt 10000} ? green : red">th:classappend 테스트 중</h4>
<!-- th:class를 이용하면 기존에 있던 deco class 덮어쓰기 해서 밑줄 없어짐 -->
<h4 class="deco" th:class="${num1 gt 10000} ? green : red">th:classappend 테스트 중</h4>
</body>
</html>
출력 화면

{std?.age} 없으면 출력 안됨 (오류 발생 안함)
<h4 th:text="${member.memberNo}"></h4>
500 에러 -> 없는 거 검색하려고 해서
<h4 th:text="${member?.memberNo}"></h4>
아무것도 출력 안됨
-> 안전 탐색 연산자를 사용하면 오류 발생 X
<h4 th:text="${std?.studentNo}"></h4>
출력 화면

시작부터 끝까지 번호로만 이루어진 숫자 배열 생성
ex) ${#numbers.sequence(1, 5)} => [1,2,3,4,5]
타임리프 반복문 th:each 는 향상된 for문으로 일반 for문의 동작(시작부터 끝까지 몇씩 증가하며 반복)을 못하기 때문에 이를 해결하기 위해서 사용
<ul>
<!-- 11부터 시작해서 20까지 2씩 증가하며 반복 -->
<li th:each="i : ${#numbers.sequence(11, 20, 2)}"
th:text="|테스트 ${i}|"
></li>
</ul>
numbers 오타 주의
출력 화면

fragment(조각)
html 요소를 다른 html 파일에서 재사용 가능하게 함
temp.html
<div th:fragment="temp1">
<ul>
<li><a href="#">공지사항</a></li>
<li><a href="#">자유 게시판</a></li>
<li><a href="#">질문 게시판</a></li>
<li><a href="#">FAQ</a></li>
<li><a href="#">1:1문의</a></li>
</ul>
</div>
<h1 th:fragment="temp2" style="background-color: yellow; color: red;">
Thymeleaf Fragment 확인 중</h1>
main.html
<h3>fragment/temp.html 중 temp1 조각 추가하기</h3>
<!-- 타임리프가 제공하는 접두사, 접미사를 제외한 경로를 작성 -->
<th:block th:replace="~{fragments/temp :: temp1}"></th:block>
<!-- 경로 :: 조각이름 -->
<h3>fragment/temp.html 중 temp2 조각 추가하기</h3>
<th:block th:replace="~{fragments/temp :: temp2}"></th:block>
출력 화면

조각 전체 가져오기
footer.html
<hr>
<p>타임리프 연습 프로젝트 입니다.</p>
<hr>
<p>
<a href="#">고객센터</a>
|
<a href="#">1:1문의</a>
|
<a href="#">찾아오시는 길</a>
</p>
main.html
<!-- html 파일 전체를 하나의 조각으로 취급 -->
<th:block th:replace="~{fragments/footer}"></th:block>
출력 화면
