02M. ๋ถํธ์คํธ๋ฉ
02M. ๋ถํธ์คํธ๋ฉ ๊ด๋ จ
์น ๋์์ด๋ ์์ด ํผ์์ ์น ํ๋ก๊ทธ๋จ์ ์์ฑํด ๋ณด์๋ค๋ฉด ํ๋ฉด ๋์์ธ ์์ ์ ์ผ๋ง๋ ๋ง์ ์๊ฐ๊ณผ ๊ณ ๋ฏผ์ด ํ์ํ์ง ์๊ณ ์์ ๊ฒ์ด๋ค. ์ด๋ฒ์ ์๊ฐํ๋ ๋ถํธ์คํธ๋ฉ(Bootstrap)์ ๋์์ด๋์ ๋์ ์์ด๋ ๊ฐ๋ฐ์ ํผ์์ ์๋นํ ๊ด์ฐฎ์ ์์ค์ ์น ํ์ด์ง๋ฅผ ๋ง๋ค์ ์๊ฒ ๋์์ฃผ๋ ํ๋ ์์ํฌ์ด๋ค. ๋ถํธ์คํธ๋ฉ์ ํธ์ํฐ(Twitter)๋ฅผ ๊ฐ๋ฐํ๋ฉด์ ๋ง๋ค์ด์ก๊ณ ํ์ฌ ์ง์์ ์ผ๋ก ๊ด๋ฆฌ๋๊ณ ์๋ ์คํ์์ค ํ๋ก์ ํธ์ด๋ค.
๋ถํธ์คํธ๋ฉ์ ์ ์ฉํ์ฌ SBB ์๋น์ค๋ฅผ ์ด์๊ฒ ๋ง๋ค์ด ๋ณด์.
๋ถํธ์คํธ๋ฉ ์ค์น
์ฐ์ ๋ค์ URL์์ ๋ถํธ์คํธ๋ฉ์ ๋ค์ด๋ก๋ ํ์.
๐์ฐธ๊ณ ๋งํฌ: ๋ถํธ์คํธ๋ฉ ๋ค์ด๋ก๋
::: warn ๋ถํธ์คํธ๋ฉ ์ฃผ์์ฌํญ
๋ถํธ์คํธ๋ฉ์ 3.x, 4.x, 5.x ๋ฑ์ ๋ฒ์ ์ด ์กด์ฌํ๊ณ ๋ฉ์ด์ ๋ฒํธ(3, 4, 5)์ ๋ฐ๋ผ ๊ทธ ์ฌ์ฉ๋ฐฉ๋ฒ์ด ๋ค๋ฅด๋ค. ์ด ์ฑ ์ ๋ถํธ์คํธ๋ฉ ๋ฒ์ 5 ๊ธฐ์ค์ผ๋ก ์ค์ต์ ์งํํ๋ค. ๋ค๋ฅธ ๋ถํธ์คํธ๋ฉ ๋ฒ์ ์ ์ฌ์ฉํ๋ฉด ์ด ์ฑ ์ ์์ ๋ ์ ์ ๋์ํ์ง ์๋๋ค.
:::
bootstrap-5.2.3-dist.zip
์ด ์ฑ
์ ์์ฑํ๋ ์์ ์ ๋ถํธ์คํธ๋ฉ ์ต์ ๋ฒ์ ์ 5.2.3 ์ด๋ค. ์์ถํ์ผ ์์๋ ๋ง์ ํ์ผ๋ค์ด ์๋๋ฐ ์ด ์ค์์ bootstrap.min.css
ํ์ผ์ ์นดํผํ์ฌ ์คํํฑ ๋๋ ํฐ๋ฆฌ์ ์ ์ฅํ๋๋ก ํ์.
๊ตฌ๋ถ | ํ์ผ ์์น |
---|---|
์์ถํ์ผ๋ด ๊ฒฝ๋ก | bootstrap-5.2.3-dist.zip/bootstrap-5.2.3-dist/css/bootstrap.min.css |
์นดํผํ ๊ฒฝ๋ก | /sbb/src/main/resources/static/ bootstrap.min.css |
๋์ค์ ์งํ๋๋ ์ฑํฐ์์ bootstrap.min.js
ํ์ผ๋ ํ์ํ๋ bootstrap-5.2.3-dist.zip
ํ์ผ์ ์ญ์ ํ์ง ๋ง์.
๋ถํธ์คํธ๋ฉ ์ ์ฉ
๋จผ์ ์ง๋ฌธ ๋ชฉ๋ก ํ ํ๋ฆฟ์ ๋ถํธ์คํธ๋ฉ์ ๋ค์์ฒ๋ผ ์ ์ฉํ์.
ํ์ผ๋ช :
/sbb/src/main/resources/templates/
question_list.html
<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="${#temporals.format(question.createDate, 'yyyy-MM-dd HH:mm')}"></td>
</tr>
</tbody>
</table>
</div>
ํ
์ด๋ธ ํญ๋ชฉ์ผ๋ก "๋ฒํธ"๋ฅผ ์ถ๊ฐํ๋ค. ๋ฒํธ๋ loop.count
๋ฅผ ์ฌ์ฉํ์ฌ ํ์ํ๋ค. ๊ทธ๋ฆฌ๊ณ ๋ ์ง๋ฅผ ๋ณด๊ธฐ ์ข๊ฒ ์ถ๋ ฅํ๊ธฐ ์ํด ํ์๋ฆฌํ์ #temporals.format
์ ํธ๋ฆฌํฐ๋ฅผ ์ฌ์ฉํ๋ค. #temporals.format
์ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ๋ค.
#temporals.format(๋ ์ง๊ฐ์ฒด, ๋ ์งํฌ๋งท)
- ๋ ์ง๊ฐ์ฒด๋ฅผ ๋ ์งํฌ๋งท์ ๋ง๊ฒ ๋ณํํ๋ค.
๊ทธ๋ฆฌ๊ณ ๊ฐ์ฅ ์์ค์ bootstrap.min.css
์คํ์ผ์ํธ๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ๋งํฌ๋ฅผ ์ถ๊ฐํ๋ค. ๊ทธ๋ฆฌ๊ณ ์์์ ์ฌ์ฉ๋ class="container my-3"
, class="table"
, class="table-dark"
๋ฑ์ ๋ถํธ์คํธ๋ฉ ์คํ์ผ์ํธ์ ์ ์๋์ด ์๋ ํด๋์ค๋ค์ด๋ค. ๋ถํธ์คํธ๋ฉ์ ๋ํ ์์ธํ ๋ด์ฉ์ ๋ค์ URL์ ์ฐธ์กฐํ์.
์์ผ๋ก ํ ํ๋ฆฟ ์์ฑ์์ ๊ณ์ ๋ถํธ์คํธ๋ฉ ์คํ์ผ๋ค์ ์ฌ์ฉํ ๊ฒ์ด๋ค. ๋ฌผ๋ก ์ฌ์ฉํ๋ ๋ถํธ์คํธ๋ฉ ํด๋์ค๋ค์ ๋ํด์ ๊ฐ๋จํ ์ค๋ช ์ ํ๊ฒ ์ง๋ง ์ ๋ฌธ์๋ฅผ ๊ฐ๋จํ๊ฒ๋ผ๋ ํ๋ฒ ๋จผ์ ์ฝ์ด๋ณด๊ธฐ๋ฅผ ๋น๋ถํ๋ค.
์ด์ด์ ์ง๋ฌธ ์์ธ ํ ํ๋ฆฟ์๋ ๋ค์์ฒ๋ผ ๋ถํธ์คํธ๋ฉ์ ์ ์ฉํ์.
ํ์ผ๋ช :
/sbb/src/main/resources/templates/
question_detail.html
<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="${#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์ฝ๋๋ฅผ ์์ฑํด์ผ ํ๋ค. ํ์ง๋ง ์ด๋ ต์ง ์์ผ๋ ์ฐฌ์ฐฌํ ์ดํด๋ณด์. ์ง๋ฌธ์ด๋ ๋ต๋ณ์ ํ๋์ ๋ญ์น์ ํด๋นํ๋ฏ๋ก ๋ถํธ์คํธ๋ฉ์ 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;"
๊ณผ ๊ฐ์ ์คํ์ผ์ ์ง์ ํด ์ฃผ์๋ค. ๊ธ ๋ด์ฉ์ ์ค ๋ฐ๊ฟ์ ์ ์์ ์ผ๋ก ๋ณด์ฌ์ฃผ๊ธฐ ์ํด ์ ์ฉํ ์คํ์ผ์ด๋ค.
๋ถํธ์คํธ๋ฉ์ ์ฌ์ฉํ๋ฉด ์ ๋ง ๋น ๋ฅด๊ฒ ๋ง์กฑ์ค๋ฌ์ด ํ๋ฉด์ ๋ง๋ค ์ ์๋ค.