thymeleaf 템플릿 엔진은 서버에서 클라이언트측으로 데이터를 전달하고 html에 표시할 수 있는 서버측 Expression Language를 제공한다.
html에서 thymeleaf를 사용할때
<html xmlns:th="http://www.thymeleaf.org">
html에 xml namespace "http://www.thymeleaf.org로 설정
thymeleaf의 prefix는 th이다.
expressions
- ${...} : variable expressions //변수
- *{...} : selection expressions //선택된 변수의 하위 프로퍼티
- #{...} : message(i18n) expressions //국제화
- @{...} : link(url) expressions //link
- ~{...} : fragment expressions //코드조각
<div th:fragment="left" th:remove="tag">
<p>
<strong>메 뉴</strong>
</p>
<ul>
<li><a href="guest_main">방명록홈</a></li>
<li><a href="guest_list">방명록리스트</a></li>
<li><a href="guest_write_form">방명록쓰기폼</a></li>
</ul>
</div>
- th:fragment="name"
코드 조각에 이름을 설정해주면 코드조각을 사용할 수 있다.
- th:remove="tag"
다른 템플릿에서 코드조각을 사용할 때 제거하고 싶은 부분이 있을 때 사용한다.
위 코드에선 "left" fragment 를 다른 곳에 삽입 했을 때 <div>태그 내의 내용은 삽입되지만 <div>태그는 remove된다.
navigation bar, header, footer 같이 많은 페이지에서 사용하는 템플릿은 fragment로 지정하여 하나의 템플릿으로 모아서 사용할 수 있다.
<div id="header" th:insert="~{include_common :: top}">
공통으로 들어가는 top header부분에 name="top"인 fragment를 삽입
th:insert="~{include_common::top}"
~{html :: fragmentName} : fragment expression
include_common.html 파일의 top fragment
<div id="header" th:insert="include_common :: top">
~{} expression을 생략해도 적용이 되긴한다.
<tr th:each="guest:${guestList}">
<a href="guest_view?guest_no=223" th:href="@{guest_view(guest_no=${guest.guest_no})}" class="user" th:text="${guest.guest_title}">타이틀</a>
<td width=120 align=center bgcolor="ffffff" th:text="${guest.guest_date.substring(2,10)}">2023-09-11</td>
</tr>
${variable} : variable expressions
th:each 반복문
th:each="사용할 단위객체 변수명(guest):객체배열(${guestList})"
이후 속성 scope 내에서 guest를 사용할 수 있다.
th:href="@{link url}"
th:text
text를 덮어씌운다.
<form name="f" method="post" th:object="${guest}">
<input type="hidden" th:field="*{guest_no}"/>
<table>
<tr>
<td>번호</td>
<td th:text="*{guest_no}">159</td>
</tr>
th:object="객체"
th:object를 지정해주면 해당 태그 내에서 *selection expression 사용할 수 있다.
기존에는 ${object.field} 로 접근하였다면 object를 지정해주면 *{field}로 object를 생략하고 field를 쓸 수 있다.
th:field="데이터 바인딩 하려는 모델객체의 필드네임"
th:field 속성은 name과 id를 자동으로 생성해주고 value값을 바인딩해준다.
<input type="hidden" th:field="*{guest_no}"/>
<input type="hidden" name="guest_no" id="guest_no" value="*{guest_no}" th:value="*{guest_no}"/>
위 th:field 속성을 사용하면 아래와 유사하다고 생각하면 된다.
<div th:fragment="left" th:remove="tag" >
<p>
<strong th:text="#{menu.title}">메뉴</strong>
</p>
<th:block th:if="${session.sUserId!=null}">
<ul>
<li><a href='user_view' th:text="${#messages.msg('menu.id',session.sUserId)}"> 땡땡님</a></li>
<li><a href='user_view' th:text="#{menu.myinfo}">내정보</a></li>
<li><a href="user_logout_action" th:text="#{menu.logout}">로그아웃</a></li>
</ul>
</th:block>
<th:block th:unless="${session.sUserId!=null}">
<ul>
<li><a href="user_login_form" th:text="#{menu.login}">로그인</a></li>
<li><a href="user_write_form" th:text="#{menu.join}">회원가입</a></li>
</ul>
</th:block>
</div>
위 navigation bar "left" fragment의 업그레이드버전이다.
로그인 상태와 로그인 하지 않은 상태에 따라 메뉴를 다르게 표시하게 하였다.
<th:block th:if="${session.sUserId!=null}">
th의 태그인 <th:block>을 사용하여 다르게 설정할 부분을 묶고 th:if 속성을 사용하였다.
model의 데이터는 바로 가져올 수 있었지만
session의 데이터는 session을 거쳐야 했다.
"${session.sUserId}"
th:if="boolean값"
th:unless="boolean값"
<th:block th:if="${session.sUserId!=null}">
<th:block th:unless="${session.sUserId!=null}">
th:if => true이면 실행
th:unless => false이면 실행
th:text="#{menu.myinfo}"
messages 설정파일의 key값 menu.myinfo의 value를 #{message expression}으로 가져온다.
menu.id={0} 님
user.properties에 설정한 다국어 message map이다.
{0} 으로 인자를 한개 받는다.
기존 #{message} 에 인자를 받는 부분이 추가로 필요하다.
<th:text="#{menu.id(${session.sUserId})}">떙떙님
<th:text="${#messages.msg('menu.id', session.sUserId)}">떙떙님
parameter를 변수로 받을 때 표현식이다.
1.#{messageKey(${param})}
기존 #{messageKey}에 (변수) 를 추가한다.
2.${#messages.msg('messageKey',param)}
메세지를 처리하기 위한 유틸리티 객체 #messages.msg() 함수를 이용해 값을 받는다.
https://www.thymeleaf.org/documentation.html
Documentation - Thymeleaf
Articles Quick glimpses into what Thymeleaf can bring to your project. Introductions With Spring Comparisons
www.thymeleaf.org
타임리프 document
'Java > Spring Boot' 카테고리의 다른 글
Spring CRUD with RestAPI (0) | 2023.09.20 |
---|---|
Spring addViewControllers (0) | 2023.09.14 |
Spring Interceptor (0) | 2023.09.14 |
JSTL coreTag (0) | 2023.09.13 |
Spring CustomTag SPEL(Spring Expression Language) (0) | 2023.09.13 |