thymeleaf 사용하기 반복, 생략, params, if

이태규·2022년 3월 13일
1

spring

목록 보기
12/64

thymeleaf를 사용하는 이유

보다시피 thymeleaf 문법으로 쓰여진 HTML templates는 항상 마크업 언어 안쪽에 속성으로 쓰여지기 때문에 HTML 페이지처럼 보이고 실제로 동작하는데 그것은 natural templates라고 부른다. 톰캣같은 서버가 동작하지 않아도 HTML 페이지가 잘 보이기 때문에 마크업을 쉽게 수정할 수 있고 다른 view Template-Engine처럼 해당 문법을 사용하여 전체적인 마크업 구조를 흐트러 트리지 않는다는 점에서 매력적인 부분이다. 또한 애플리케이션을 개발할때 디자인과 개발이 분리되어 작업 효율을 향상시킬 수 있는것이다.

마치.. static한 html파일을 수정하는 느낌이랄까? ...

Thymeleaf의 장점 정리

natural templates : HTML 처럼 보이고 HTML 처럼 사용할 수 있다.
was를 통하지 않고 파일을 브라우저를 통해 열 수 있음(브라우저가 해석 가능한 마크업 언어만이 존재하기 때문에) 그리하여 퍼블리셔와 협업이 용이함.
오직 html에는 마크업 언어만 존재하기 때문에 마크업 구조를 흐트러트리지 않아 시각적으로 편함.

출처: https://pugyu.tistory.com/75

Thymeleaf 사용하기

  1. pom.xml에 dependency 추가하기
<!-- jsp에서 반복문 사용하기(타임리프) -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
  1. application.properties에 jsp 위치 설정하기

#jsp 위치설정(어느 폴더에 어떤 확장자)

spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.jsp
  1. html에 넣기
<html lang="ko" xmlns:th="http://www.thymeleaf.org">

Thymeleaf 주요 기능

텍스트 - text, utext : 텍스트를 출력하는 기능

th:text="${data}"
th:utext="${data}"

${} 는 변수 표현식을 의미
[[$]]는 컨텐츠 안에서 직접 출력
<span th:text="${data}">Hello</span>

<span th:utext="${data}">Hello</span>

<span>[[${data}]]</span>

utext를 사용하는 이유?
모델에 <원하는 태그>라는 태그를 달고 싶어서 data에 "<태그>Hello! Thymeleaf</태그>" 를 담아서 보내게 되면 <부분은 <로 >부분은 >로 변경될 것 입니다. HTML에서는 <를 태그가 아닌 문자로 표현하기 위해 HTML 엔티티로 변경합니다.
이런 HTML 변경 기능을 이스케이프라고 합니다. 타임리프는 기본적으로 th:text에 이스케이프를 재공합니다.
이를 unescape하기 위해서 utext를 사용하게 됩니다.

html 중복 부분 생략하기

<태그 th:replace="~{파일 위치 :: Fragment 이름}">

<head th:replace="~{/member/header :: headerFragment}"></head>
<div th:replace="~{/member/footer :: footerFragment}"></div>

header.jsp

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">

    <head th:fragment="headerFragment">
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title th:text="${title}"></title>
        <link rel="stylesheet" type="text/css" th:href="@{/css/bootstrap.css}" />
        <script type="text/javascript" th:src="@{/js/bootstrap.min.js}"></script>    
    </head>

</html>

footer.jsp

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">

    <footer th:fragment="footerFragment">
    <a href="/home">/home</a>
    <a href="/member/insert">/member/insert</a>
    <a href="/member/selectlist">/member/selectlist</a>
    <a href="/item/insert">/item/insert</a>
    <a href="/item/selectlist">/item/selectlist</a>
    <a href="/member/login">/member/login</a>
    <a href="/member/mypage">/member/mypage</a>
    <a href="/admin/insertBatch">/admin/insertBatch</a>
    <a href="/admin/selectlist">/admin/selectlist</a>
    <a href="/board/insert">/board/insert</a>
    <a href="/board/selectlist">/board/selectlist</a>
    <a href="/board/update">/board/update</a>
    <a href="/board/selectfind">/board/selectfind</a>
    <a href="/book/insert">/book/insert</a>
    <a href="/book/selectlist">/book/selectlist</a>

    </footer>
</html>

뷰에서 컴포넌트처럼 사용하는 느낌.

파라미터의 접근도 쉽게 하기 위해 param이라는 기능도 제공

<a th:href="@{/mvc}">url</a>

<!-- 링크에 파라미터 포함-->
<a th:href="@{/mvc(param1=${param1},param2=${param2})}">url</a>
<a th:href="@{/mvc/{param1}/{param2}(param1=${param1},param2=${param2})}">url</a>
<a th:href="@{/mvc/{param1}(param1=${param1},param2=${param2})}">url</a>
@{/mvc(param1=${param1},param2=${param2})} : /mvc?param1=data1&param2=data2
@{/mvc/{param1}/{param2}(param1=${param1},param2=${param2})} : /mvc/data1/data2
@{/mvc/{param1}(param1=${param1},param2=${param2})} : /mvc/data1?param2=data2
이렇게 해석 됩니다!

리터럴

리터럴은 소스 코드 상에 고정된 값을 의미
타임 리프에서는 th:text="'hello'" 이런 식으로 사용.
공백이 없을 시에는 th:text="hello" '' 생략 가능.

하지만 원칙상 감싸야 하는 것이지, 매번 이렇게 작은따옴표로 문자 리터럴을 감싸기에는 매우 번거롭다

그래서 타임리프의 경우 문자열이 공백없이 이어질 경우 하나의 토큰으로 인지하여 작은따옴표를 생략할 수 있다

<span th:text="spring">text</span>

여기서 주의해야 할 점은 공백없이 이어져야 한다는 것이다

만약 아래와 같이 글자 사이에 공백이 있다면 타임리프가 하나의 토큰으로 인지하지 못하기 때문에 에러가 발생한다

th:text="hello spring" 이처럼 공백이 있을 때에는 오류. ''(작은 따옴표)로 감싸야함

<span th:text="'spring thymeleaf'">text</span> 
//spring 과 thymeleaf 사이에 공백이 있지만 정상작동

이 외에도 변수와 함께 사용할 수 있다

<span th:text="'spring' + ${variable}">text</span>

이렇게 변수와 함께 사용할 때 혹은 그냥 문자 리터럴을 사용할 때도 타임리프가 제공하는 더욱 편리한 방법이 있는데

바로 리터럴 대체 문법이다

Literal Substitions

리터럴 대체
||을 사용
th:text="|hello ${data}|" 이렇게 사용. ${data} 가 변수의 값으로 바뀜.

//리터럴 대체 문법 
<span th:text="|welcome!, ${user.name}!|">text</span>

//변수 + 리터럴 대체 문법 
<span th:text="|welcome to ${page.name}| + ' ' +${user.name}">text</span>

반복

th:each 사용

<tr th:each="tmp, idx : ${list}">
                <td th:text="${tmp.id}"></td>
                <td th:text="${tmp.name}"></td>
                <td th:text="${tmp.age}"></td>
                
반복에서는 신기한 기능도 있습니다.
th:each="member:${members}" 이 상황에서 th:each="member, 
memberStat:${members}" 처럼 두번 째 파라미터도 가질 수 있습니다.
두번 째 파라미터가 하는 일은 반복 상태에 대하여 보여 줍니다

조건식

th:if, th:unless(th:if의 반대)
th:switch, case

<!-- if, unless-->
th:if="${member.age == 10}"
th:unless="${member.age ge 10}"

<!--switch-->
th:switch="${member.age}"
	th:case="10"
	th:case="20"

블록

반복문 같은 것을 사용 시 애매할 때 자주 사용

<th:block th:each="i : ${#numbers.sequence(1,pages)}">

        <a th:href="@{/book/selectlist(page=${i}, text=${param.text})}" 
        th:text="${i}"></a>
    </th:block>
profile
한 걸음씩 나아가자

0개의 댓글