2-15, 3-01 요약 (표준 html 구조로 작성하기, layout 작성, 네비게이션 만들기)
2-15 표준 HTML 구조로 작성하기
모든 html 템플릿 파일에는 표준 HTML 구조에 해당하는 요소들이 중복되어 작성될 수 있다.
타임리프는 이런 중복의 불편함을 해소하기 위해 템플릿 상속 기능을 제공한다.
템플릿 상속이란,
기본 틀이 되는 템플릿을 먼저 작성하고, 다른 템플릿에서 그 템플릿을 상속해 사용하는 방법이다.
중복되는 요소들은 "기본 틀"이 관리하고, "내용"에 해당하는 부분만 각 화면 별로 작성한다.
1) layout.html 로 기본 틀을 만든다.
templates 디렉터리 아래 common 폴더를 만들고, 아래와 같이 layout.html 파일을 작성해 주었다.
<!doctype html>
<html lang="ko">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" type="text/css" th:href="@{/bootstrap.min.css}">
<!-- board CSS -->
<link rel="stylesheet" type="text/css" th:href="@{/style.css}">
<title>게시판 프로젝트 입니다</title>
</head>
<body>
<!-- 네비게이션 영역 -->
<div th:replace="~{common/navbar :: navbarFragment}"></div>
<!-- 기본 템플릿 안에 삽입될 내용 Start -->
<th:block layout:fragment="content"></th:block>
<!-- 기본 템플릿 안에 삽입될 내용 End -->
<!--부트스트랩 js-->
<script th:src="@{/bootstrap.min.js}"></script>
<!-- 자바스크립트 Start -->
<th:block layout:fragment="script"></th:block>
<!-- 자바스크립트 End -->
</body>
</html>
layout.html 은 모든 템플릿이 상속해야 하는 템플릿으로, 표준 HTML 문서 구조로 정리된 기본 틀이다.
표준 HTML 문서 구조는, html, head, body 요소가 있어야 하며, css 파일은 head 태그 안에 링크되어야 한다.
또한, head 태그 안에는 meta, title 요소 등이 포함되어야 한다.
script 태그는 </body> 태그 바로 위에 선언해준다. (화면이 모두 작성이 된 후 스크립트가 실행돼야 오류가 나지 않음)
body 태그 안의
<th:block layout:fragment="content"></th:block> , <th:block layout:fragment="script"></th:block> 부분이
layout.html 을 상속한 템플릿에서 개별적으로 구현해야 하는 영역이 된다.
2) question.html 과 questionDetail.html 과 같은 템플릿 화면에 아래와 같이 레이아웃을 상속한다.
<html layout:decorate="~{common/layout}">
<div layout:fragment="content" class="container my-3">
<!-- 내용 작성 부분 -->
</div>
<script layout:fragment="script" type='text/javascript'>
<!-- 스크립트도 동일하게 이런식으로 layout:fragment 를 주고 이 영역에 작성 -->
</script>
</html>
layout.html 파일에서 layout:fragment 속성으로 content 와 script 의 위치가 지정되었다.
템플릿 파일에서 div 태그와 script 태그에 layout:fragment="content" , layout:fragment="script" 값을 주었고,
div 태그와 script 태그 안에 내용을 작성하면 된다.
템플릿에서 fragment 의 내용를 작성하면,
해당 fragment 에 맞게 layout.html에 끼워 맞춰진다고 생각하면 된다.
3-01 네비게이션 바 추가하기
위 layout.html 에서 <div th:replace="~{common/navbar :: navbarFragment}"></div> 라고 작성한 영역이 네비게이션 영역이다.
네비게이션도 모든 "템플릿" 에서 보여야 하므로, layout 에서 관리한다.
쉬운 유지보수를 위해 navbar.html 파일을 따로 작성하였고,
layout.html 파일에서 navbar.html 파일을 불러오도록 replace 태그를 통해 연결해주었다.
아래는 navbar.html 의 코드이다.
<!--공통 템플릿으로 뺄때는 th:fragment 선언 필수. 다른 html에 고대로 붙일때는 이 선언만 빼면 됨 -->
<nav th:fragment="navbarFragment" class="navbar navbar-expand-lg navbar-light bg-light border-bottom">
<div class="container-fluid">
<a class="navbar-brand" href="/">BOARD</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<!--sec:authrize 속성 : 사용자의 로그인여부에 따라 요소를 출력하거나 출력하지 않음 -->
<a class="nav-link" sec:authorize="isAnonymous()" th:href="@{/user/login}">로그인</a>
<a class="nav-link" sec:authorize="isAuthenticated()" th:href="@{/user/logout}">로그아웃</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/user/signup">회원가입</a>
</li>
</ul>
</div>
</div>
</nav>
navbar.html 의 nav 태그에는 th:fragment="navbarFragment" 라 선언한다.
layout.html 에서는 <nav th:replace="~{navbar :: navbarFragment}"></nav> 라고 선언한다.
* 위 코드는 부트스트랩을 활용하여 내비게이션 바를 생성하는 내용이므로,
static 디렉터리에 bootstrap.min.css , bootstrap.min.js 가 모두 있어야 오류 없이 동작한다.