참고 링크 : https://wikidocs.net/book/7601
오라클DB와 intelliJ로 작업하였습니다
부트스트랩(Bootstrap)은 디자이너의 도움 없이도 개발자 혼자서 상당히 괜찮은 수준의 웹 페이지를 만들수 있게 도와주는 프레임워크이다. 부트스트랩은 트위터(Twitter)를 개발하면서 만들어졌고 현재 지속적으로 관리되고 있는 오픈소스 프로젝트이다. 부트스트랩을 적용하여 SBB 서비스를 이쁘게 만들어 보자.
부트스트랩 설치
우선 다음 URL에서 부트스트랩을 다운로드 하자.
부트스트랩 다운로드 - https://getbootstrap.com/docs/5.1/getting-started/download/
점프 투 스프링부트부트스트랩 주의사항
부트스트랩은 3.x, 4.x, 5.x 등의 버전이 존재하고 메이저 번호(3, 4, 5)에 따라 그 사용방법이 다르다. 이 책은 부트스트랩 버전 5 기준으로 실습을 진행한다. 다른 부트스트랩 버전을 사용하면 이 책의 예제는 정상 동작하지 않는다.
부트스트랩 다운로드 페이지 접속후 "Download" 버튼을 누르면 다음과 같은 파일이 다운로드 된다.
bootstrap-5.1.3-dist.zip
이 책을 작성하는 시점의 부트스트랩 최신 버전은 5.1.3 이다. 압축파일 안에는 많은 파일들이 있는데 이 중에서 bootstrap.min.css 파일을 카피하여 스태틱 디렉터리에 저장하도록 하자.
구분파일 위치
압축파일내 경로 | bootstrap-5.1.3-dist.zip/bootstrap-5.1.3-dist/css/bootstrap.min.css |
카피할 경로 | /sbb/src/main/resources/static/bootstrap.min.css |
나중에 진행되는 챕터에서 bootstrap.min.js 파일도 필요하니 bootstrap-5.1.3-dist.zip 파일을 삭제하지 말자.
부트스트랩 적용
먼저 질문 목록 템플릿에 부트스트랩을 다음처럼 적용하자.
question_list.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>질문 목록</title>
</head>
<body>
<link rel="stylesheet" type="text/css" th:href="@{/bootstrap.min.css}"> <!--스타일시트사용 링크추가-->
<div 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="${#dates.format(question.createDate, 'yyyy-MM-dd HH:mm')}"></td> <!--날짜객체 날짜포맷에맞게 변환-->
</tr>
</tbody>
</table>
</div>
</body>
</html>
테이블 항목으로 "번호"를 추가했다. 번호는 loop.count를 사용하여 표시했다.
th:each="question, loop : ${questionList}"
추가한 loop 객체를 이용하여 루프 내에서 다음과 같은 속성을 사용할수 있다.
- loop.index - 반복 순서, 0부터 1씩 증가
- loop.count - 반복 순서, 1부터 1씩 증가
- loop.size - 반복 객체의 요소 갯수 (예: questionList의 요소 갯수)
- loop.first - 루프의 첫번째 순서인 경우 true
- loop.last - 루프의 마지막 순서인 경우 true
- loop.odd - 루프의 홀수번째 순서인 경우 true
- loop.even - 루프의 짝수번째 순서인 경우 true
- loop.current - 현재 대입된 객체 (예: 위의 경우 question과 동일)
그리고 날짜를 보기 좋게 출력하기 위해
타임리프의 #dates.format유틸리티를 사용했다.#dates.format은 다음과 같이 사용한다.
- #dates.format(날짜객체, 날짜포맷) - 날짜객체를 날짜포맷에 맞게 변환한다.
dd가 아닌 DD는 1월1일부터 해당월일까지의 일수가 나옴...
그리고 가장 윗줄에 bootstrap.min.css 스타일시트를 사용할수 있도록 링크를 추가했다.
<link rel="stylesheet" type="text/css" th:href="@{/bootstrap.min.css}">
그리고 위에서 사용된 class="container my-3", class="table", class="table-dark 등은 부트스트랩 스타일시트에 정의되어 있는 클래스들이다. 부트스트랩에 대한 자세한 내용은 다음 URL을 참조하자.
앞으로 템플릿 작성시에 계속 부트스트랩 스타일들을 사용할 것이다.
이제 다음처럼 부트스트랩이 적용된 질문 목록을 볼 수 있을 것이다.
이어서 질문 상세 템플릿에도 다음처럼 부트스트랩을 적용하자.
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>질문 상세</title>
</head>
<body>
<link rel="stylesheet" type="text/css" th:href="@{/bootstrap.min.css}"> <!--부트스트랩 링크추가-->
<div 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="${#dates.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>
<!--#list.size(이터러블객체)-타임리프가 제공하는 유틸리티로 객체의 길이를 반환-->
<!--답변 반복 시작-->
<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="${#dates.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>
</body>
</html>
이번에는 수정사항이 좀 많다. 부트스트랩으로 화면을 구성하다 보면 가끔은 이렇게 많은 양의 HTML코드를 작성해야 한다. 하지만 어렵지 않으니 찬찬히 살펴보자. 질문이나 답변은 하나의 뭉치에 해당하므로 부트스트랩의 card 컴포넌트를 사용했다.
- 부트스트랩 card 컴포넌트 : https://getbootstrap.com/docs/5.1/components/card/
질문 상세 템플릿에 사용한 부트스트랩 클래스를 다음처럼 표로 정리하였다.
부트스트랩 클래스설명
card, card-body, card-text | 부트스트랩 Card 컴포넌트 |
badge | 부트스트랩 Badge 컴포넌트 |
form-control | 부트스트랩 Form 컴포넌트 |
border-bottom | 아래방향 테두리 선 |
my-3 | 상하 마진값 3 |
py-2 | 상하 패딩값 2 |
p-2 | 상하좌우 패딩값 2 |
d-flex justify-content-end | 컴포넌트의 우측 정렬 |
bg-light | 연회색 배경 |
text-dark | 검은색 글씨 |
text-start | 좌측 정렬 |
btn btn-primary | 부트스트랩 버튼 컴포넌트 |
그리고 질문 내용과 답변 내용에는 style="white-space: pre-line;" 과 같은 스타일을 지정해 주었다. 글 내용의 줄 바꿈을 정상적으로 보여주기 위해 적용한 스타일이다.
부트스트랩을 적용한 질문 상세 화면은 다음과 같다.
'Follow Work > SpringbootBoard' 카테고리의 다른 글
[StringBoot] 질문 등록과 폼 (12) (0) | 2022.08.15 |
---|---|
[StringBoot] 템플릿상속 (11) (0) | 2022.08.12 |
[StringBoot] 스태틱 디렉터리와 스타일시트 (9) (0) | 2022.08.12 |
[StringBoot] 답변등록 (8) (0) | 2022.08.12 |
[StringBoot] 질문상세 (7) (0) | 2022.08.12 |