07_02 Thymeleaf 사용

송지윤·2024년 4월 11일

Spring Boot

목록 보기
15/71

삼항 연산자

타임리프 속성(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>

출력 화면

Elvis 연산자 ( ?: )

[작성법]
값 ?: 값이 없을 때

  • 삼항 연산자에서 조건식 자리에 값(변수명)만 작성
    (==, != 등의 연산자 사용 X)

  • 우변에는 값이 없을 때에 대한 값만 작성

  • 조건식값이 존재하면 해당 값을 출력
    없으면 우변을 출력

-> 해당 값이 있는지 없는지에 따라 동작하는 연산자

html

    <p th:text="${member} ?: '회원 데이터 없음'"></p>

    <p th:text="${std} ?: '학생 데이터 없음'"></p>

출력 화면

No-Operation 연산자 (값 ?: _)

  • 조건식의 값이 없을 경우 (== null)
    타임리프 코드를 해석하지 않는 연산자

  • 타임리프 코드 해석 X
    -> 일반 HTML 태그로 동작
    -> HTML 태그 사이 내용(content)이 화면에 출력

html

    <!-- 회원 데이터 없음 -->
    <p th:text="${member} ?: _">회원 데이터 없음</p>

    <!-- std.toString() 결과 출력 -->
    <p th:text="${std} ?: _">학생 데이터 없음</p>

th:inline

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>

th:classappend 속성

요소에 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>

출력 화면

안전 탐색 연산자 : ${객체?.필드명}

  • 객체가 null인지 판단 후 null이 아닌 경우에 수행 (javascript에서도 사용)

std.age안에값없으면오류발생함{std.age} 안에 값 없으면 오류 발생함{std?.age} 없으면 출력 안됨 (오류 발생 안함)

<h4 th:text="${member.memberNo}"></h4>

500 에러 -> 없는 거 검색하려고 해서

<h4 th:text="${member?.memberNo}"></h4>

아무것도 출력 안됨
-> 안전 탐색 연산자를 사용하면 오류 발생 X

<h4 th:text="${std?.studentNo}"></h4>

출력 화면

${#numbers.sequence(시작, 끝 [, step])} : 번호 발생기

  • 시작부터 끝까지 번호로만 이루어진 숫자 배열 생성
    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 오타 주의

출력 화면

th:fragment / th:replace

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>

출력 화면

0개의 댓글