Thymeleaf 정리

JongPark·2024년 1월 12일

정리

목록 보기
3/3
post-thumbnail

ㆍ Thymeleaf 특징

  • Server Side Template Engine
  • 순수 HTML을 최대한 유지하면서 사용할 수 있다. ( Natural Template )
  • 프로젝트를 Jar 파일로 Export할 수 있다.
  • Auto Escape 가 적용된다. ( HTML 이스케이프를 자동으로 처리하여 XSS 공격을 방어 )
  • 스프링과 자연스럽게 통합 가능하다. ( 예를 들어, Spring Security를 Thymeleaf에서 사용 가능하다. )
  • 매우 풍부한 EL ( SpringEL 사용 가능 )
  • Tomcat과 같은 WebServer 없이 구동 가능하다. ( 디자이너, 퍼블리셔가 작업할 때 WAS 실행을 하지 않아도 된다. )
  • HTTP Request Params, Session, Spring Bean 등에 접근 가능하다.
  • 전체 국제화를 지원한다.
  • Request, Session, Response, ServletContext, Locale등과 같은 내장 객체를 제공해준다.
  • Servlet API에 대한 강한 의존성이 없다.

ㆍ주된 Thymeleaf 사용 이유

  • Spring에서 Thymeleaf 사용 권장 ( 표준 )
  • 화면 개발 코드에는 화면을 표현하기 위한 코드만 남겨놓음 ( 더욱 완벽한 MVC 구현, 유지보수 용이 )
  • HTML Tag 구조를 오염시키지 않음 ( 퍼블리셔, 프론트 개발자와 의사소통하기 편해짐 )
  • SSR 이지만 디자인만 확인할 수 있도록 HTML 오픈 가능 ( 디자이너와 협업 )

ㆍ Thymeleaf 사용 시 주의점?

  • 지원하는 기능이 많은 만큼 배워야 할 양도 많다. 협업하는 개발자의 수가 많을수록 이를 배우고 각각에 대한 규칙을 명세한 뒤 익히는 Learning Curve가 상당히 완만해질 것이다.
  • JSP에서 내부 코드를 작성하지 않고 주의점들을 최대한 다 보완하며 사용하면 굳이 템플릿 엔진을 변경할 필요가 있을까?

ㆍ Thymeleaf 기본문법

  • th:text
<div th:text = "${user.name}"></div>  // 컨트롤러에서 전달받은 객체의 값을 text로 렌더링
<div th:utext = "${data}"></div>      // 태그의 속성을 적용해서 출력

<div>[[${user.name}]]</div>  // th:text 기능을 직접 데이터 출력
<div>[(${data})]</div>  // th:utext 기능을 직접 데이터 출력
  • th:href
    <a> 태그에 링크 경로를 동적으로 입력할 때 또는 오브젝트에 저장된 데이터를 가져올때 사용한다.
<a th:href = "@{/home}">
=> /home

<a th:href = "@{/home(param1 = ${value1}, param2 = ${value2})}">
 => /home?param1=value1&param2=value2

<a th:href = "@{/home/{param1}/{param2}(param1 = ${value1}, param2 = ${value2})}">
 => /home/value1/value2
 
<a th:href = "@{/home/{param1}(param1 = &{value1}, param2 = ${value2})}">
 => /hello/value1?param2=value2
  • th:src
    <img> 태그에 이미지 경로를 동적으로 입력할 때, 또는 오브젝트에서 경로가 저장된 데이터를 가져와서 사용한다.
<img th:src="@{/images/home}+${imagePath}">
  • th:with
    변수형태의 값을 재정의하는 것으로 값이 있다면 정의하고 없다면 다른 값으로 정의한다.
<th:block th:with="value=${#strings.defaultString(user.name, '')}">

<div th:with = "dataFlag = ${(data == null || data.getId() == '') ? false : true}">
  
<input type = "text" th:value = "${dataFlag? data.getBool() : ''}">
  • th:attr
    태그 안의 attribute를 타임리프로 정의할 때 사용한다.
<div th:attr = "testValue = ${user.name}"></div>
 -> testValue = 홍길동
 
<div th:attr = "bool = ${user.check == '1' ? 'true' : 'false'}">
  • th:value
    input에 데이터를 넣을 때 사용한다.
<input type = "hidden" th:value = ${value.name}>
  • th:block
    Thymeleaf 문법을 어느 곳에서든 사용할 수 있도록 한다. 타임리프의 유일한 자체 태그로 여러 태그를 반복할 경우 사용한다. <th:block> 태그는 렌더링 시 제거된다.
<th:block th:if = "${item != null}">
  <a th:href="@{${item.link}}" th:text="${item.name}" 
	th:attr="current = ${item.link == other.link && item.target != '2' ? 'page' : ''}"></a>
</th:block>

<th:block th:each = "item : ${itemList}">
  <a th:href = "@{${item.link}}" th:text = "${item.name}"></a>
</th:block>
  • th:if / th:unless
<th:if = "${user == null}"> // 조건이 만족할 시 렌더링
<th:unless = "${user != null}"> // 조건이 만족하지 않을 시 렌더링
<th:if = "${menu.type == '2'}"> // type이 2일경우 렌더링
<th:if = "${Object != null}"> // null이 아닐경우 렌더링
  • th:switch / th:case
<th:switch = "${user.age}">
<th:case = "10">
<th:case = "20">
<th:case = "*"> //케이스에 없을 경우
  • th:each
<div th:each = "data : ${dataList}"> // dataList 객체에 대하여 반복
  <div th:text = "${data.name}"></div>
  <div th:text = "${data.type}"></div>
</div>
  • List<E>
<div th:text = "${nameList[3]}"></div>
 -> 리스트의 인덱스로 데이터를 가져 올 수 있음
 
<div th:with = "user = ${userList[1]}" th:text = "${user.name}"></div>
 -> 객체 리스트의 경우에 with를 이용해 지역변수에 담아서도 사용 가능
 
<th:block th:each = "user : ${userList}" >
  <div th:text = "${user.name}"></div>
</div>
 -> 타임리프 반복문을 이용해 차례대로 객체를 담아올 수 있음
  • Map<K,V>
<th:block th:with = "entry : ${valueList}">
  <div th:if="${entry.key != 'A'}" th:text="${entry.value}"></div>
</th:block>
  • List<Map<K,V>>
<th:block th:with="value = ${valueList[4]}">
  <div th:text="${value.get('NAME')}"></div>
</th:block>
-> list의 인덱스 순서로 map 데이터를 가져올 수 있다.
  • xmlns:layout / layout:decorator
<html lang="ko" xmlns:th="http://www.thymeleaf.org" 
  xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" 
  layout:decorate="~{board/layout/basic}"> // layout:decorate를 이용해 공통양식의 경로를 지정한다
  • th:fragment

웹페이지에서 네비게이션바 등의 header영역과 관련사이트, 저작권 표시 등 footer영역처럼 반복되는 영역들이 존재하는데, 이 공통 영역들을 th:fragment로 정의하여 한 번 만들어 놓은 HTML을 반복해서 사용할 수 있게 한다. th:fragment로 조각화 하고 사용하고자 하는 HTML에서 th:replace = "~{파일경로 :: fragment이름}"을 통해 삽입한다.

<th:block th:fragment="footerFragment">
  <footer id="footer">
    <div>관련 사이트</div>
    <button type="button" title="선택된 관련 사이트 새창으로 열기">이동</button>
  </footer>
</th:block>
  • th:replace
    fragment로 조각화한 공통 소스를 HTML에 삽입하는 역할을 한다.
    ::를 기준으로 앞에는 조각화한 fragment의 html 경로를, 뒤에는 명명한 fragment의 이름을 넣어준다.
<div th:replace="~{layout/fragments/footer :: footerFragment}"></div>
<th:block th:replace="~{layout/fragments/footer :: footerFragment}" ></th:block>
  • th:insert
    th:replace와 동일한 기능을 하지만 차이가 있다. th:replace는 태그가 입력된 제거되고 fragment로 완전 대체되지만 th:insert는 입력된 태그 안에 fragment를 삽입할 때 사용한다.
    형식은 replace와 동일하다.
<div th:insert="~{layout/fragments/footer :: footerFragment}"></div>
<th:block th:insert="~{layout/fragments/footer :: footerFragment}"></th:block>
  • th:remove
    브라우저로 html을 열었을 때는 보이지만 타임리프 엔진에 의한 렌더링이 됐을때는 보이지 않게 하고 싶을 때 사용한다.
<th:block th:remove="tag" th:utext="${name}" th:text="${name}"></th:block>
  • th:action
    <form> 태그 사용시 해당 경로로 요청을 보낼 때 사용한다. ajax와 비슷한 기능을 수행한다.
<form name="performForm" method="get" th:action="@{performList.do}" th:object="${perform}">
  • th:object
    <form> 태그에서 해당 경로로 요청을 보낼때 데이터를 object에 담아서 보낸다. mapping된 controller에서는 요청을 수행할 때 th:object를 통해 받은 object를 사용할 수 있다.
<form th:action="@{/event/search.do}" th:object="${user}" method="post">
  
 ↓ ↓ ↓
  
@RequestMapping(value="/event/search.do")
public String searchUser(User user, HttpServletRequest request, HttpServletResponse response)
  • th:field
    th:field를 사용해서 HTML 태그에 멤버 변수를 mapping 할 수 있다.
<input type="text" id="title" name="title" title="TITLE" th:field="*{title}">
  • th:inline
    <javascript> 태그 안에서 Thymeleaf의 문법과 변수를 사용할 수 있도록 한다.
<script type="text/javascript" th:inline="javascript">
var nameList = /*[[ ${nameList} ]]*/;  // 주석 부분이 자동으로 제거됨.
</script>

0개의 댓글