HTML에 타임리프를 적용한 사례들을 정리해봤다.
기본적인 문법은 아래와 같다.
레이아웃 템플릿은 다음과 같이 정리했다
default_layout.html
<html lang="ko"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta name="_csrf" th:content="${_csrf.token}">
<meta name="_csrf_header" th:content="${_csrf.headerName}">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<link th:href="@{/css/common.css}" rel="stylesheet" />
</head>
<body>
<div class="wrap">
// replace를 이용하면 해당 템플릿을 불러올수 있다.
<th:block th:replace="/fragments/header :: headerFragment"></th:block>
<div layout:fragment="content"></div>
<th:block th:replace="/fragments/footer :: footerFragment"></th:block>
</div>
</body>
</html>
header를 불러오는 코드는 아래와 같다
header.html
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
// headerFragment 이름으로 fragment를 지정해주어 다른페이지에도 사용할 수 있도록 한다.
<div th:fragment="headerFragment" class="header">
<div class="img_box img_wrap">
<a th:href="@{/list}"><img id="bonanzaImage1" src="/img/plug.png" class="org_image" alt="보난자팩토리"></a>
</div>
<div class="menu" style="left: 20%;">
<div class="bar">
<a th:href="@{/list}" class="submenu" type="submit">이용기관 목록</a>
</div>
</div>
<div class="menu" style="left: 28%;">
<div class="bar">
<a th:href="@{/register}" class="submenu" type="submit">이용기관 등록</a>
</div>
</div>
<div class="menu" style="left: 36%;">
<div class="bar">
<a th:href="@{/goStat}" class="submenu" type="submit">일/월 정산</a>
</div>
</div>
<div class="menu" style="left: 43%;">
<div class="bar">
<a th:href="@{/goList}" class="submenu" type="submit">이용기관 거래 목록</a>
</div>
</div>
<div id="logoutBox">
<div sec:authorize="isAnonymous()">
<button class="submenu" ><a class="submenu" th:href="@{/login}">로그인</a></button>
</div>
<div sec:authorize="isAuthenticated()">
<form th:action="@{/logout}" method="post">
<span style="cursor: text" sec:authentication="name">Name</span>
<button class="submenu" type="submit">로그아웃</button>
</form>
<div sec:authorize="hasRole('ROLE_ADMIN')">
<a style="margin-left: 102px;" th:href="@{/admin}">관리자페이지 이동</a>
</div>
</div>
</div>
</div>
</html>
이처럼 footer에도 같은 방식으로 적용이 된다고 보면 된다.
이제 default_layout에서 content는 어떻게 사용할까?
content.html
아래의 코드는 개발하는 페이지 일부 코드다
layout:decorate를 이용해서 기본 레이아웃을 설정해주고,
layout:fragment="content"를 선언하여 기본 레이아웃 안에 넣어줄 코드를 생성한다.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
// 기본 레이아웃 생성
layout:decorate="~{/layout/default_layout}">
<head>
<link th:href="@{/css/corpInfo.css}" rel="stylesheet" />
</head>
<body>
// content 내용 삽입
<div layout:fragment="content" class="content">
<h2>이용기관 정보</h2>
<!-- 아래의 코드를 추가 합니다.-->
<table border="1" class="type2">
<tr>
<th>사업자명</th>
<th>이용기관명</th>
<th>사업자 등록번호</th>
<th>전화번호</th>
<th>주소</th>
<th>상태</th>
</tr>
<tr>
<td th:text="${ corp.corpName }"></td>
<td th:text="${ corp.clientName }"></td>
<td th:text="${ corp.corpNumber }"></td>
<td th:text="${ corp.tel }"></td>
<td th:text="${ corp.address }"></td>
<td th:text="${ corp.statusCd }"></td>
</tr>
</table>
<br/>
<table border="1" class="type2">
<tr>
<th>클라이언트 코드</th>
<th>Access Token</th>
<th>유효시간(초)</th>
<th>Refresh Token</th>
<th>Token Type</th>
</tr>
<tr>
<td th:text="${ corp.clientId }"></td>
<td th:text="${ corp.accessToken }"></td>
<td th:text="${ corp.expiresIn }"></td>
<!--
<td><a th:href="@{/token(clientId=${ corp.clientId })}" class="btn btn-primary">토큰 갱신하기</a></td>
-->
<td>토큰 갱신하기(X)</td>
<td th:text="${ corp.tokenType }"></td>
</tr>
</table>
<br/>
<h2>서비스 목록</h2>
<table border="1" class="type2">
<tr>
<th:block th:each="service : ${services}">
<td th:text="${ service }"></td>
</th:block>
</tr>
</table>
<form action="#" th:action="@{/updateSettleCode}" th:object="${settleCode}" method="POST">
<input type="text" th:field="*{clientId}" placeholder="이용기관코드" class="form-control mb-4 col-4 readonly" readonly>
<input type="text" th:field="*{serviceCode}" placeholder="서비스코드" class="form-control mb-4 col-4 input">
<input type="text" th:field="*{settleCode}" placeholder="정산코드" class="form-control mb-4 col-4 input">
<input type="text" th:field="*{reservedAt}" placeholder="적용일시 YYYYMMDD000000" class="form-control mb-4 col-4 input">
<button type="submit" class="btn btn-info col-2 custom-btn btn-13">서비스코드 추가/변경</button>
</form>
<br/>
<h2>하위 이용기관 목록</h2>
<!-- 작성란&버튼 -->
<!-- 하위이용기관 목록 -->
<table border="1" class="type2">
<tr>
<th>하위이용기관 코드</th>
<th>하위이용기관명</th>
<th>상태정보</th>
<th>등록일자</th>
<th>수정일자</th>
</tr>
<th:block th:each="subOrg : ${subOrgList}">
<tr>
<td th:text="${ subOrg.sub_org_id }"></td>
<td th:text="${ subOrg.name }"></td>
<td th:text="${ subOrg.status_cd }"></td>
<td th:text="${ subOrg.created_at.date }"></td>
<td th:text="${ subOrg.updated_at.date }"></td>
</tr>
</th:block>
</table>
<form action="#" th:action="@{/subRegister}" th:object="${subOrg}" method="POST">
<input type="text" th:field="*{clientId}" placeholder="이용기관코드" class="form-control mb-4 col-4 readonly" readonly>
<input type="text" th:field="*{name}" placeholder="하위 이용기관명" class="form-control mb-4 col-4 input">
<button type="submit" class="btn btn-info col-2 custom-btn btn-13">하위 이용기관 추가</button>
</form>
<hr>
<a th:href="@{/update(clientId=${ corp.clientId })}" class="btn btn-primary btn-sm mb-3"> 이용기관 정보 변경 </a>
</div>
</body>
</html>
코드를 살펴보면 JSP에서 JSTL 방식을 쓰던 것 과 비슷하게 여러 종류의 문법을 사용 하여 데이터 조회가 가능하다.
마지막으로 스크립트를 살펴본다
script
<script th:inline="javascript">
[# th:if="${param.error}"]
alert("계정 또는 OTP가 유효하지 않습니다.");
[/]
[# th:if="${param.logout}"]
alert("로그아웃 성공");
[/]
</script>
script에 th:inline을 선언하여 스크립트에서 타임리프를 이용할 수 있다. 이 밖에도 사용되는 문법의 형태가 다양해서 구현하고자 하는 페이지가 있으면 사용방법을 찾아서 사용하면 될 것 같다.