[MVC2] 1. 타임리프 - 기본기능

kiwonkim·2021년 8월 27일
0
post-thumbnail

타임리프(Thymeleaf)란?

자바를 기반으로 하는 템플릿 엔진 중 하나. 템플릿 엔진이란 데이터를 미리 정의된 템플릿에 넣어 HTML을 그리는 소프트 웨어를 가리킨다. 타임리프는 컨트롤러의 로직 수행 결과를 바탕으로 동적 서버 사이드 렌더링(SSR)에 활용된다. 또한 순수 HTML을 유지하며 뷰 템플릿도 사용 가능한 네츄럴 템플릿의 특징을 갖고, 스프링과 유연한 통합을 지원한다.

타임리프는 View단에서 Controller 의 파라미터를 바탕으로 HTML을 그리는 라이브러리이다.



텍스트 & 변수 출력

텍스트 변수 출력

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

타임리프는 주로 HTML 태그 속성에 기능을 정의 하여 사용한다.
텍스트 변수의 출력의 경우 th:text 태그로 출력 가능하다.
뷰가 렌더링 되면 th가 포함된 속성을 인식하여 동적으로 렌더링하게 된다.

이 때 텍스트 변수에 <> 등이 포함되어 있으면 태그가 아닌 문자로 변경시켜주는 HTML 엔티티가 동작한다.
이를 끄고 변수 내 <> 등을 태그로 활용하려면 th:utext 속성을 사용하면 된다.


컨텐츠 내 변수 출력

또한 모든 파라미터 변수는 경우 [[$변수명]]을 통해 컨텐츠 내 출력 가능하다.

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

SpringEL

위와 같이 타임리프는 변수 표현시 ${...} 으로 된 변수 표현식을 사용한다.
이 때 SpringEL은 다양한 표현식으로 변수 접근을 용이하게 해준다.

  • 객체변수 접근
<span th:text = "${user.name}"> // user 변수의 name 속성에 접근. get함수 자동호출됨.
//user.getUsername() 한 것과 같은 효과.
  • List변수 접근
<span th:text = "${users[0].name}"> // users 리스트 변수의 0번째 객체의 name 속성에 접근
  • Map변수 접근
<span th:text = "${userMap['userA'].name}"> //Map에서 userA 찾고 name속성에 접근


기본 객체 & 편의 객체 & 유틸리티 객체

기본 객체

${#request}
${#response}
${#session}

같은 기본 객체들 제공.

이때 파라미터는 ${#request.getParameter("paramData") 처럼 불편하게 접근해야 하므로 편의 객체 또한 제공한다.


편의 객체

${param}  // request에 바인딩된 파라미터 접근
ex) ${param.paramData}   -> paramData 파라미터에 접근 

${session}  // session에 바인딩된 속성 접근
ex) ${session.sessionData}  -> sessionData 속성에 접근

${@}     // 스프링 빈 접근
ex) ${@helloBean.hello('Spring!')}    -> helloBean 빈 객체에 hello 메서드 호출

유틸리티 객체

${#message} //메시지 처리
${#dates} // 날짜 서식 지원
${#calendars} //Calendar 서식 지원

등 필요에 따라 사용 가능한 여러 유틸리티 객체 제공



URL 링크

타임리프에서 URL 생성시 @{...} 를 사용.

단순 URL

<a th:href="@{/hello}>    -> /hello

쿼리 파라미터

<a th:href="@{/hello(param1=${param1}, param2=${param2})}> 

-> /hello?param1=data1&param2=data2

// () 안 부분은 쿼리파라미터가 됨.

경로 변수

<a th:href="@{/hello/{param1}/{param2}(param1=${param1}, param2=${param2})}>

-> /hello/data1/data2

// URL 경로상 {} 의 변수가 있다면 () 안은 경로 변수로 처리됨.

경로 변수 + 쿼리 파라미터

@{/hello/{param1}(param1=${param1}, param2=${param2})}

-> /hello/data1?param2=data2

// 경로변수와 쿼리파라미터 동시 사용 가능. 
// () 안에서 {} 안 변수와 매핑되는 부분은 경로변수. 나머지는 쿼리파라미터가 됨.

@{...}을 활용하여 동적으로 변하는 URL을 생성할 수 있다.

th: 로 이루어진 속성들은 뷰 렌더링이 아니면 무시된다. - 네츄럴 템플릿의 특징



리터럴

리터럴은 고정된 변수를 의미한다.

문자 : 'hello' -> 문자의 경우 항상 ''를 포함해야함에 유의
숫자 : 10
불린 : true, false
null : null

<span th:text> = "'hello' + ' world!'">
<span th:text> = "'hello' + ${data}">
<span th:text> = "|hello ${data}|">    // || 활용 리터럴 대체 문법.


연산

th:text 속성 내에서 비교&조건 등의 연산이 가능하다.

//비교
<span th:text="1 gt 10">  -> false
<span th:text="1 != 10">  -> false

//조건
<span th:text="(10 % 2 == 0)? '짝수':'홀수'">

//Elvis 연산자 - 조건문 편의 버전
<span th:text="${data}?: '데이터가 없습니다.'">

//No-opeation - _ 인 경우 th 자체가 없는 것처럼 동작. 네츄럴 템플릿 활용 가능
<span th:text="${data}?: _">데이터가 없습니다.</span>


속성 값 설정

타임리프는 HTML태그에 th: 속성을 추가하는 방식으로 동작. 기존 HTML에 속성이 존재할 경우 이를 대체하게 됨.

<input type="text" name="A" th:name="B" />
-> 브라우저로 열면 name = A. 뷰 렌더링으로 열면 name = B 가 됨.

타임리프는 기존 HTML 태그 속성에 값을 추가할 수도 있다.

<input type="text", class="text" th:attrappend="class='large'" />
-> class 속성 뒤에 리터럴 large를 추가. textlarge 가 됨.

<input type="text", class="text" th:attrpreappend="class='large'" />
-> class 속성 앞에 리터럴 large를 추가. largetext 가 됨.


반복문

타임리프에서 반복은 th:each 속성을 사용한다.

<tr th:each="user, userStat : ${users}">

-> users 리스트 변수를 순회하며 하나씩 user 객체에 담아 태그를 반복 실행함.

리스트 뿐 아니라 배열, Map 등에도 적용할 수 있다.

-> 두번째 파라미터인 userStat은 반복의 상태 확인 객체이며 생략 가능.

태그 내에서 userStat.index, userStat.count, userStat.size 등의 변수를 활용 할 수 있다.


조건 태그

th:if , th:unless 속성으로 사용하며. 뒤의 값이 true 일때만 해당 태그가 반영된다.

<span th:text="'미성년자'" th:if="${user.age lt 20}">
-> user.age 가 20보다 작을때만 '미성년자' 리터럴 문자열 출력

th:switch 와 th:case 를 이용해 스위치 구문도 사용 가능하다.

<td th:switch="${user.age}">
    <span th:case="10">10살</span>
    <span th:case="20">20살</span>
    <span th:case="*">기타</span>  -> switch의 디폴트


타임리프 주석

  1. 기존 HTML 주석
<!-- -->
HTML 주석은 타임리프가 그대로 남겨둠
  1. 타임리프 파서 주석
<!--/* 내용 */-->

<!--/*-->
내용
<!--*/-->

타임리프 파서 주석은 타임리프가 렌더링시 제거함
  1. 타임리프 프로토타입 주석
<!--/*/
내용
/*/-->

타임리프 프로토타입 주석은 HTML을 그대로 열어보면 주석처리되지만
타임리프 렌더링 시에만 내용이 렌더링됨.


블록

<th:block> 으로 태그를 생성하며 타임리프의 유일한 자체 태그이다.
여러 태그를 묶어서 반복시 사용한다.

<th:block th:each="user : ${users}">
    <div>
    	이름
        나이
    </div>
    <div>
    	요약
    </div>
</th:block>

타임리프는 태그에 속성을 추가하여 사용하는데, 두 개의 div 태그를 한번에 반복처리할 방법이 없기에 이럴 때 블록 태그를 사용한다.



자바스크립트 인라인

<script th:inline="javascript"> 로 사용하며
타임리프에서 자바스크립트를 사용하고. 그 안에서 변수들을 사용할때 여러 편의기능을 제공한다.
자바스크립트 인라인은 세 가지 기능을 한다.

  1. 텍스트 렌더링
    var username = [[${user.username]]

    인라인 전 : username = userA;
    인라인 후 : username = "userA";

    텍스트 변수를 변수에 대입할시 ""를 자동으로 추가해준다.

  1. JS에서 내추럴 템플릿 적용
    var username2 = /[[${user.username}]]/ "test username";

    인라인 전 : username2 = /userA/ "test username";
    인라인 후 : username2 = "userA"

    /* */ 를 활용하여 내추럴 템플릿을 적용하도록 해준다.

  2. 객체 JSON 변환
    var user = [[${user}]];

    인라인 전 : user = BasicController.User(username=userA, age = 10);
    인라인 후 : user = {"username":"userA", "age":10);

    객체를 JS에서 쓰기 쉽도록 JSON으로 변환해준다.



템플릿

템플릿 조각

웹 페이지에 상단, 푸터 등 공통 영역이 존재하고 수정이 필요할 경우 이를 일일이 수정하는 것은 비효율적.
타임리프는 이를 위해 템플릿 조각과 레이아웃 기능을 제공함.

템플릿 생성
<footer th:fragment="copy">
	푸터입니다.
</footer>

<footer th:fragment"copyParam (param1, param2)">
	파라미터 입니다.
    <p th:text="${param1}"></p>
    <p th:text="${param2}"></p>
</footer>
템플릿 사용

현 div 태그 안에 위의 copy 조각 삽입
<div th:insert="~{template/fragment/footer :: copy}"</div>

현 div 태그를 위의 copy 조각으로 대체
<div th:replace="~{template/fragment/footer :: copy}"</div>

copy 조각으로 대체. 단순 표현식
<div th:replace="template/fragment/footer :: copy"</div>

copyParam을 메서드처럼 사용. 데이터1, 데이터2를 넘겨주며 호출.
<div th:repalce="~{template/fragment/footer :: 
		copyParam ('데이터1', '데이터2')}"</div>

템플릿 활용 레이아웃

범용 레이아웃을 만들어놓고, 조각을 대입하여 사용

범용 레이아웃
<html th:fragment="layout (title, content)">

확장 Main
<html th:replace="~{template/layoutExtend/layoutFile 
		:: layout(~{::title}, ~{::section})};
  1. 확장 Main은 범용 레이아웃에게 자신의 title 태그와 section 태그 값들을 넘겨준다.

  2. 범용 레이아웃은 이를 title과 content 삼아 자신을 렌더링 한다.

  3. 확장 Main은 replace를 통해 자신을 2번 결과로 대체한다.

-> 즉 확장 Main은 넘겨주는 파라미터에 따라 변경된 레이아웃을 자신으로 하게됨.



본 글은 김영한님의 "스프링 MVC 2편 - 백엔드 웹 개발 활용 기술" 강의내용 및 이해한 내용을 정리한 것입니다.

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2/dashboard

0개의 댓글

관련 채용 정보