하나씩 차근차근
article thumbnail

앞에서 만든 question_list.html 과 question_detail.html 은 body 태그의 바깥 부분은 동일한 내용입니다.

이후 다른 html 파일을 만들게 되더라도 body 태그의 바깥 부분은 계속 동일하기 때문에 

템플릿을 상속받아 기본틀을 만들고 그 안에 내용을 채우는 방식으로 진행하겠습니다.

 

시작

제일 먼저 thymeleaf 의 layout 기능을 사용하기 위해 pom.xml 파일에 라이브러리를 추가합니다.

<dependency>
	<groupId>nz.net.ultraq.thymeleaf</groupId>
	<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>

 

기본틀

다음과 같이 기본틀이 되는 layout.html 파일을 templates 폴더 안에 생성합니다.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Spring Boot Board</title>
</head>
<body>
	<th:block layout:fragment = "content"></th:block>
</body>
</html>

위 코드에서 body 태그 안의 layout:fragment 부분에 기존에 작성된 내용들이 채워지면서 

브라우저를 통해 보여집니다.

 

question_list 수정

다음으로 question_list.html 파일의 중복되는 부분을 삭제하고

기본틀이 되는 layout.html 을 상속받고 body 태그 안으로 넣을 수 있도록 수정하겠습니다.

<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 : ${questionList}">
					<td th:text="${question.id}"></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>

첫번째 줄의 layout:decorate = "~{layout}" 을 통해 layout.html 파일을 상속받아 bootstrap 과 css 를 사용하게 되고

layout:fragment = "content" 를 통해 layout.html 의 body 부분에 삽입됩니다.

 

question_detail 수정

동일한 방법으로 question_detail.html 파일도 수정합니다.

<html layout:decorate = "~{layout}">
	<div layout:fragment="content" class="container my-3">
		<h1 class="border-bottom py-2" th:text = "${question.subject}"></h1>
		
		<div clas="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')}"></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 class="my-3" th:action="@{|/answer/create/${question.id}|}" method="post">
			<textarea class="form-control" name="content" id="content" rows="15"></textarea>
			<input class="btn btn-primary my-2" type="submit" value="답변등록">
		</form>
	</div>
</html>

 

결과

브라우저로 접속해서 개발자도구를 통해 question_list 파일의 소스를 보면

다음과 같이 head 부분에 layout.html 을 상속받아 사용하고 있는것을 알 수 있습니다.

question_detail 파일도 동일하게 layout.html 을 상속받아 사용하고 있습니다.

profile

하나씩 차근차근

@jeehwan_lee

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!