현재 우리는 표준 HTML 구조가 아닌데, 계속해서 HTML 파일을 만들 경우 굉장히 귀찮다. 또 중복되는 것들이 굉장히 많아진다. 예를들어
<link rel="stylesheet" type="text/css" th:href="@{/bootstrap.min.css}">
<link rel="stylesheet" type="text/css" th:href="@{/style.css}">
위 같은 코드를 계속 적어줘야 하는데 여간 귀찮은게 아니다.
그러면 HTML의 <head>태그 부분에 중복되는 코드를 넣어 계속해서 상속하여 가져올 수 있는 방법이 있을까?
이 때 템플릿 상속을 이용한다.=
1. 템플릿 상속을 위한 layout.html 파일 생성
표준 HTML 구조가 되는 **layout.html**을 생성하자.
// templates/layout.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" type="text/css" th:href="@{/bootstrap.min.css}">
<link rel="stylesheet" type="text/css" th:href="@{/style.css}">
<title>Jaesoon SBB</title>
</head>
<body>
<th:block layout:fragment="content"></th:block>
</body>
</html>
이 부분을 상속시켜주면 표준 HTML 구조가 완성된다.
body 내부에 <th:block layout:fragment="content"></th:block> 라는 코드가 있는데, layout.html 을 상속한 템플릿에서 개별적으로 구현하는 곳이다.
2. 각 html파일 수정
// question_list.html
<html layout:decorate="~{layout}">
<div layout:fragment="content" class="container my-3">
<table class="table">
<thead class="table-dark">
<tr>
<th>번호</th>
<th>제목</th>
<th>작성일시</th>
</tr>
</thead>
<tbody>
<tr th:each="question, loop : ${questionList}">
<td th:text="${loop.count}"></td>
<td>
<a th:href="@{|/question/detail/${question.id}|}" th:text="${question.subject}"></a>
</td>
<td th:text="${#temporals.format(question.createDate, 'yyyy-MM-dd HH:mm')}"></td>
</tr>
</tbody>
</table>
</div>
</html>
// question_detail.html
<html layout:decorate="~{layout}">
<div layout:fragment="content" class="container my-3">
<!-- 질문 -->
<h2 class="border-bottom py-2" th:text="${question.subject}"></h2>
<div class="card my-3">
<div class="card-body">
<div class="card-text" style="white-space: pre-line;" th:text="${question.content}"></div>
<div class="d-flex justify-content-end">
<div class="badge bg-light text-dark p-2 text-start">
<div th:text="${#temporals.format(question.createDate, 'yyyy-MM-dd HH:mm')}"></div>
</div>
</div>
</div>
</div>
<!-- 답변의 갯수 표시 -->
<h5 class="border-bottom my-3 py-2"
th:text="|${#lists.size(question.answerList)}개의 답변이 있습니다.|"></h5>
<!-- 답변 반복 시작 -->
<div class="card my-3" th:each="answer : ${question.answerList}">
<div class="card-body">
<div class="card-text" style="white-space: pre-line;" th:text="${answer.content}"></div>
<div class="d-flex justify-content-end">
<div class="badge bg-light text-dark p-2 text-start">
<div th:text="${#temporals.format(answer.createDate, 'yyyy-MM-dd HH:mm')}"></div>
</div>
</div>
</div>
</div>
<!-- 답변 반복 끝 -->
<!-- 답변 작성 -->
<form th:action="@{|/answer/create/${question.id}|}" method="post" class="my-3">
<textarea name="content" id="content" rows="10" class="form-control"></textarea>
<input type="submit" value="답변등록" class="btn btn-primary my-2">
</form>
</div>
</html>
처음보는 부분이 존재하는데, <html layout:decorate=”~{layout}”> 태그가 있다.
layout:decorate 부분은 thymeleaf의 속성인데 템플릿의 상속될 템플릿을 설정한다.
속성값 “~{layout}”은 layout.html을 의미한다.
그 후
<div layout:fragment="content" class="container my-3"></div>
부분이 존재하는데,
부모 템플릿(layout.html)의 th:block 속성에 대한 내용이 자식 템플릿(question_~~~.html)의 내용으로 변경하기 위해 사용하는 것이다.
코드를 보면 표준 HTML에 맞게 나온다!
'Spring' 카테고리의 다른 글
[Spring]Spring 시작해보기(13) - 답변 등록 오류 (0) | 2022.08.17 |
---|---|
[Spring]Spring 시작해보기(12) - 질문 등록 버튼 및 폼 생성 (0) | 2022.08.16 |
[Spring]Spring 시작해보기(10) - BootStrap, Font 적용 (0) | 2022.08.16 |
[Spring]Spring 시작해보기(9) - 답글 달기 form 생성 및 출력 (0) | 2022.08.16 |
[Spring]Spring 시작해보기(8) - 상세 페이지 만들기 (0) | 2022.08.16 |