티스토리 뷰

본 포스팅은 백기선님의 스프링과 JPA 기반 웹 애플리케이션 개발 강의를 참고하여 작성하였습니다.
소스 코드는 여기 있습니다. (commit hash: a7de4fe)

> git clone https://github.com/lcalmsky/spring-boot-app.git
> git checkout a7de4fe

ℹ️ squash merge를 사용해 기존 branch를 삭제하기로 하여 앞으로는 commit hash로 포스팅 시점의 소스 코드를 공유할 예정입니다.

Overview

이번 포스팅에서는 내비게이션 바에 아이콘 추가하고, 프로필 기본 이미지(아바타)를 설정합니다.

라이브러리 설치

사용할 라이브러리를 static resource 디렉토리에 설치합니다.

> cd src/main/resources/static
> npm install font-awesome
> npm install jdenticon

font-awesome은 다양한 아이콘을 만들어주는 라이브러리 입니다.

jdenticon은 문자열에 맞게 임의의 아바타를 생성해주는 라이브러리 입니다.

HTML 수정

이전 포스팅에서 작성한 fragments.html 파일의 head fragment 부분에 font-awesome stylesheet와 jdenticon script를 추가해줍니다.

그리고 이왕 script를 head에 추가한 김에 기존에 index.html에 있던 script도 옮겨주도록 하겠습니다.

이전 포스팅에 포함되어야 할 내용이 조금 있는데 강의를 따라가다보니 순서가 약간 뒤죽박죽이 되는 점이 아쉽네요 😞

<head th:fragment="head">
    <meta charset="UTF-8">
    <title>Webluxible</title>
    <link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.min.css"/>
    <link rel="stylesheet" href="/node_modules/font-awesome/css/font-awesome.min.css"/> <!--font-awesome 추가-->
    <script src="/node_modules/jquery/dist/jquery.min.js"></script> <!--index.html에서 옮김-->
    <script src="/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <!--index.html에서 옮김-->
    <script src="node_modules/jdenticon/dist/jdenticon.min.js"></script> <!--jdenticon script 추가-->
    <style>
        .container {
            max-width: 100%;
        }
    </style>
</head>

그리고 같은 파일 내 navigation-bar fragment에서 텍스트를 아이콘으로 대체하겠습니다.

소스 코드가 길어 수정한 부분에 주석을 추가하였습니다.

<nav th:fragment="navigation-bar" class="navbar navbar-expand-sm navbar-dark bg-dark">
    <a class="navbar-brand" href="/" th:href="@{/}">
        <img src="/images/logo.png" width="30" height="30">
    </a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-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 mr-auto">
            <li class="nav-item">
                <form th:action="@{/search/study}" class="form-inline" method="get">
                    <input class="form-control mr-sm-2" name="keyword" type="search" placeholder="스터디 찾기"
                           aria-label="Search"/>
                </form>
            </li>
        </ul>

        <ul class="navbar-nav justify-content-end">
            <li class="nav-item" sec:authorize="!isAuthenticated()">
                <a class="nav-link" th:href="@{/login}">로그인</a>
            </li>
            <li class="nav-item" sec:authorize="!isAuthenticated()">
                <a class="nav-link" th:href="@{/sign-up}">가입</a>
            </li>
            <li class="nav-item" sec:authorize="isAuthenticated()">
                <a class="nav-link" th:href="@{/notifications}">
                    <i class="fa fa-bell-o" aria-hidden="true"></i> <!--"알림" 문자열을 종 모양 아이콘으로 수정-->
                </a>
            </li>
            <li class="nav-item" sec:authorize="isAuthenticated()">
                <a class="nav-link btn btn-outline-primary" th:href="@{/notifications}">
                    <i class="fa fa-plus" aria-hidden="true"></i> 스터디 개설 <!--"스터디 개설" 문자열 앞에 플러스 아이콘 추가-->
                </a>
            </li>
            <li class="nav-item dropdown" sec:authorize="isAuthenticated()">
                <a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown"
                   aria-haspopup="true" aria-expanded="false">
                    <svg data-jdenticon-value="user127" th:data-jdenticon-value="${#authentication.name}" width="24" height="24" class="rounded border bg-light"></svg><!--"프로필" 대신 아바타 이미지를 보여줌-->
                </a>
                <div class="dropdown-menu dropdown-menu-sm-right" aria-labelledby="userDropdown">
                    <h6 class="dropdown-header">
                        <span sec:authentication="name">Username</span>
                    </h6>
                    <a class="dropdown-item" th:href="@{'/profile/' + ${#authentication.name}}">프로필</a>
                    <a class="dropdown-item">스터디</a>
                    <div class="dropdown-divider"></div>
                    <a class="dropdown-item" href="#" th:href="@{'/settings/profile'}">설정</a>
                    <form class="form-inline my-2 my-lg-0" action="#" th:action="@{/logout}" method="post">
                        <button class="dropdown-item" type="submit">로그아웃</button>
                    </form>
                </div>
            </li>
        </ul>
    </div>
</nav>

여기까지 작성 후 애플리케이션을 실행한 뒤 가입, 이메일 인증을 하게되면 아이콘과 프로필 아바타가 잘 적용된 것을 확인할 수 있습니다.

개인적으로 프론트엔드 문외한이라 빨리 이 부분을 넘어가고싶네요 ㅜㅜ

다음 포스팅에서는 현재 인증된 사용자의 정보를 참조하는 방법을 공부하고 그것을 이용해 인증을 마치지 않은 사용자에게 경고창을 띄우는 방법에 대해 다뤄보겠습니다.

댓글