5 min to read
[스프링부트 시리즈20] 네비게이션 바 추가하기
네비게이션 바 추가하기
웹 서비스 개발자는 서비스 이용자가 편하게 사용할 수 있도록 작은 기능 하나에도 공을 들인다. 지금까지 우리는 질문 목록, 질문 상세, 질문 등록, 답변 등록 등 굵직한 기능을 중심으로 SBB 서비스를 구현했지만 이제부터는 사용자가 이 서비스를 좀 더 편리하게 이용할 수 있도록 다양한 기능을 구현해 보려고 한다.
먼저, 어떠한 화면에 있더라도 항상 메인 화면으로 돌아갈 수 있도록 내비게이션 바를 만들어 화면 상단에 고정해 보자.
네비게이션 바 만들기
1) 내비게이션 바는 모든 화면 위쪽에 고정되어 있는 부트스트랩의 컴포넌트 중 하나이다. 내비게이션 바는 모든 페이지에서 공통으로 보여야 하므로 다음과 같이 layout.html
템플릿에 내용을 추가하자.
부트스트랩의 내비게이션 바를 자세히 알고 싶다면 https://getbootstrap.com/docs/5.3/components/navbar/를 참고하자.
[파일명:/templates/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}">
<!-- sbb CSS -->
<link rel="stylesheet" type="text/css" th:href="@{/style.css}">
<title>Hello, sbb!</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light border-bottom">
<div class="container-fluid">
<a class="navbar-brand" href="/">SBB</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">
<a class="nav-link" href="#">로그인</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- 기본 템플릿 안에 삽입될 내용 Start -->
<th:block layout:fragment="content"></th:block>
<!-- 기본 템플릿 안에 삽입될 내용 End -->
</body>
</html>
이 코드는 부트스트랩(Bootstrap)을 활용하여 내비게이션 바를 생성하는 내용을 작성한 것이다. 이와 같이 <li>
태그를 활용하여 내비게이션 바에 메뉴를 추가할 수 있다.
2) 이제 브라우저에서 질문 목록 페이지를 요청하면 화면 상단에 다음과 같은 내비게이션 바가 보일 것이다. 질문 목록 페이지 외에 질문 상세나 질문 등록 페이지에서 내비게이션 바의 SBB 로고를 클릭하면 바로 메인 페이지인 질문 목록 페이지로 돌아갈 수 있다. SBB 로고를 클릭해 제대로 작동하는지 확인해 보자.
내비게이션 바의 숨은 기능 알기
1) 이 내비게이션 바에는 재미있는 기능이 하나 숨어 있다. 한번 아무 페이지나 접속해서 브라우저의 가로 사이즈를 마우스를 이용하여 점점 줄여 보자. 그러면 어느 순간 햄버거 메뉴 버튼이 생긴다. 이와 동시에 로그인 링크는 사라진다. 이와 같이 부트스트랩(Bootstrap)은 브라우저의 크기가 작아지면 자동으로 내비게이션 바에 있는 링크들을 햄버거 메뉴 버튼으로 숨긴다.
햄버거 메뉴 버튼으로 링크나 메뉴를 숨기는 것은 부트스트랩의 반응형 웹 기능이다. 반응형 웹은 웹 디자인 기법 중 하나로, 디스플레이의 크기나 종류에 반응하여 그에 맞도록 UI 요소가 자동으로 배치되도록 설계한 웹을 말한다.
2) 햄버거 메뉴 버튼을 클릭하면 숨어 있는 로그인 링크가 보여야 한다. 하지만 현 상태에서는 햄버거 메뉴 버튼을 클릭해도 아무런 변화가 없다. 햄버거 메뉴 버튼을 활용할 수 있도록 이번에는 부트스트랩 자바스크립트 파일(bootstrap.min.js
)을 static 디렉터리로 복사해 보자.
부트스트랩의 기능 중에는 자바스크립트를 사용하는 것들이 있다. 그중 하나가 바로 내비게이션 바이다.
bootstrap.min.js
파일은 이러한 부트스트랩의 특별한 기능들을 수행하는데 필요한 내용이 담긴 자바스크립트 파일이다.
드래그 앤 드롭으로 bootstrap.min.js를 static 디렉터리로 복사한다.
3) 이제 추가한 자바스크립트(Javascript, JS) 파일을 사용할 수 있도록 layout.html의 </body> 태그 바로 위에 다음과 같이 추가하자.
[파일명:/templates/layout.html]
<!doctype html>
<html lang="ko">
(... 생략 ...)
<!-- 기본 템플릿 안에 삽입될 내용 Start -->
<th:block layout:fragment="content"></th:block>
<!-- 기본 템플릿 안에 삽입될 내용 End -->
<!-- Bootstrap JS -->
<script th:src="@{/bootstrap.min.js}"></script>
</body>
</html>
부트스트랩의 JS 파일을 사용하겠다는 주석과 함께 이와 같이 JS 파일을 추가했다.
4) 이렇게 수정하면 햄버거 메뉴 버튼 클릭 시 숨어 있는 링크가 다음과 같이 표시되는 것을 확인할 수 있다.
내비게이션 바 분리하기
2-16절에서 우리는 오류 메시지를 표시하는 공통 템플릿을 작성해서 질문 등록과 질문 상세 템플릿에 삽입했다. 내비게이션 바도 공통 템플릿으로 활용해 보자.
1) 다음과 같이 내비게이션 바를 활용하기 위한 공통 템플릿으로 navbar.html
를 작성해 보자.
[파일명:/templates/navbar.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="/">SBB</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">
<a class="nav-link" href="#">로그인</a>
</li>
</ul>
</div>
</div>
</nav>
‘내비게이션 바 만들기’에서
layout.html
에 추가한 내용을 복사해 만들면 된다.
2) 다시 layout.html
로 돌아가 navbar.html
에 작성한 내용을 모두 삭제한 후, 다음과 같이 작성해 보자.
[파일명: /templates/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}">
<!-- sbb CSS -->
<link rel="stylesheet" type="text/css" th:href="@{/style.css}">
<title>Hello, sbb!</title>
</head>
<body>
<!-- 네비게이션바 -->
<nav th:replace="~{navbar :: navbarFragment}"></nav>
<!-- 기본 템플릿 안에 삽입될 내용 Start -->
<th:block layout:fragment="content"></th:block>
<!-- 기본 템플릿 안에 삽입될 내용 End -->
<!-- Bootstrap JS -->
<script th:src="@{/bootstrap.min.js}"></script>
</body>
</html>
기존의 내비게이션 바 HTML 코드들을 삭제하고 navbar.html
템플릿을 타임리프의 th:replace
속성으로 layout.html
템플릿에 포함시켰다. 사실, navbar.html
파일은 form_errors.html
처럼 다른 템플릿들에서 중복해 사용하지는 않지만 독립된 하나의 템플릿으로 관리하는 것이 유지 보수에 유리하므로 이와 같이 분리했다. 공통 템플릿을 따로 관리하는 것은 코드의 재사용성을 높여 줄 뿐만 아니라 코드의 유지 보수에도 도움이 된다.