Thymeleaf 이용하여 레이아웃 만들기

2022. 10. 4. 21:47프로젝트/Spring Boot

실습환경

 

inetllij(인텔리제이)

 

 

실습하기

Thymeleaf 사용하여 공통적인 부분 통합하기 - common.html 작성

templates → fragments(폴더 만듬) → common.html 파일을 만듭니다.

 

 

https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#including-template-fragments

 

Tutorial: Using Thymeleaf

1 Introducing Thymeleaf 1.1 What is Thymeleaf? Thymeleaf is a modern server-side Java template engine for both web and standalone environments, capable of processing HTML, XML, JavaScript, CSS and even plain text. The main goal of Thymeleaf is to provide a

www.thymeleaf.org

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">

  <body>
  
    <div th:fragment="copy">
      &copy; 2011 The Good Thymes Virtual Grocery
    </div>
  
  </body>
  
</html>

 

 

우선 thymeleaf에 정의되어있는 양식을 붙여넣습니다. 

※ Ctrl + F 검색으로 fragement 검색하여 양식을 찾습니다.

 

 

 

 

index.html

 

 

common.html

양식을 붙여넣은 이후 <div> ~ </div> 부분을 index.html의 <nav>~</nav> 부분을 붙여넣습니다.

※ nav 부분이 공통적으로 보여지는 화면이기 때문입니다.

추가로 common.html의 nav 태그 안에는 th(thymeleaf 언어) : fragment 를 추가합니다.

※ th:fragment ="(이름)"

 

 

 

 

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">

<body>

<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top" th:fragment="menu">
  <a class="navbar-brand" href="#">SUNShower</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarsExampleDefault">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" href="#">홈 <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">게시판</a>
        <!--      </li>-->
        <!--      <li class="nav-item">-->
        <!--&lt;!&ndash;        <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>&ndash;&gt;-->
        <!--      </li>-->
        <!--      <li class="nav-item dropdown">-->
        <!--        <a class="nav-link dropdown-toggle" href="#" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>-->
        <!--        <div class="dropdown-menu" aria-labelledby="dropdown01">-->
        <!--          <a class="dropdown-item" href="#">Action</a>-->
        <!--          <a class="dropdown-item" href="#">Another action</a>-->
        <!--          <a class="dropdown-item" href="#">Something else here</a>-->
        <!--        </div>-->
        <!--      </li>-->
    </ul>
    <!--    <form class="form-inline my-2 my-lg-0">-->
    <!--      <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">-->
    <!--      <button class="btn btn-secondary my-2 my-sm-0" type="submit">Search</button>-->
    <!--    </form>-->
  </div>
</nav>

</body>

</html>

최종적으로 common.html 은 위와같은 코드로 완성됩니다. 

 

 

 

 

index.html

nav 태그 안에 th:replace 언어를 추가합니다. 

※ th:replace="(경로) :: (이름)"

 

 

 

 

common.html에 작성했던 공통적인 nav 부분을 주석처리하고 실행해보겠습니다.

 

 

 

 

정상적으로 실행되고 있음을 확인할 수 있습니다.

 

 

 

 

 

게시판 틀 만들기 - BoardController

 

controller → BoardController 클래스를 만듭니다.

 

package com.example.layoutblog.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/board")
public class BoardController {
    @GetMapping("/list")
    public String list(){
        return "board/list";
    }
}

BoardController 클래스는 위와같이 작성합니다.

 

GetMapping으로 /board/list 로 경로를 지정해줬으므로 Templates 에도 똑같이 만들어줍니다.

 

 

index.html에는 html 태그에 thymeleaf가 추가되지 않아 추가시킵니다.

index.html


 

list.html

<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<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" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
  <link href="starter-template.css" rel="stylesheet">
  <title>SUNShower</title>
</head>
<body>
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top" th:replace="fragments/common :: menu">
<!--  <a class="navbar-brand" href="#">SUNShower</a>-->
<!--  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">-->
<!--    <span class="navbar-toggler-icon"></span>-->
<!--  </button>-->

<!--  <div class="collapse navbar-collapse" id="navbarsExampleDefault">-->
<!--    <ul class="navbar-nav mr-auto">-->
<!--      <li class="nav-item active">-->
<!--        <a class="nav-link" href="#">홈 <span class="sr-only">(current)</span></a>-->
<!--      </li>-->
<!--      <li class="nav-item">-->
<!--        <a class="nav-link" href="#">게시판</a>-->
<!--&lt;!&ndash;      </li>&ndash;&gt;-->
<!--&lt;!&ndash;      <li class="nav-item">&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash;        <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash;      </li>&ndash;&gt;-->
<!--&lt;!&ndash;      <li class="nav-item dropdown">&ndash;&gt;-->
<!--&lt;!&ndash;        <a class="nav-link dropdown-toggle" href="#" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>&ndash;&gt;-->
<!--&lt;!&ndash;        <div class="dropdown-menu" aria-labelledby="dropdown01">&ndash;&gt;-->
<!--&lt;!&ndash;          <a class="dropdown-item" href="#">Action</a>&ndash;&gt;-->
<!--&lt;!&ndash;          <a class="dropdown-item" href="#">Another action</a>&ndash;&gt;-->
<!--&lt;!&ndash;          <a class="dropdown-item" href="#">Something else here</a>&ndash;&gt;-->
<!--&lt;!&ndash;        </div>&ndash;&gt;-->
<!--&lt;!&ndash;      </li>&ndash;&gt;-->
<!--    </ul>-->
<!--&lt;!&ndash;    <form class="form-inline my-2 my-lg-0">&ndash;&gt;-->
<!--&lt;!&ndash;      <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">&ndash;&gt;-->
<!--&lt;!&ndash;      <button class="btn btn-secondary my-2 my-sm-0" type="submit">Search</button>&ndash;&gt;-->
<!--&lt;!&ndash;    </form>&ndash;&gt;-->
<!--  </div>-->
</nav>

<main role="main" class="container">

  <div class="starter-template">
    <h1>Spring Boot Tutorial</h1>
    <p class="lead">Spring Boot를 이용해 웹 페이지 제작<br> Spring Security, JPA를 이용해 보안 설정과 데이터 다루기</p>
  </div>

</main>

<!-- Optional JavaScript; choose one of the two! -->
<!--Option 2: jQuery, Popper.js, and Bootstrap JS-->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js" integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s" crossorigin="anonymous"></script>

</body>
</html>

이후 index.html에 있는 모든 내용을 list.html에 붙여넣습니다.

 

 

 

 

link 태그 안에 th:href 언어를 추가합니다.

※ th:href="@{(링크)}"

 

 

 

 

게시판 글자 뜨는 위치가 어색하여 수정하였습니다.

 

 

 

 

<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<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" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
    <link href="starter-template.css" th:href="@{/starter-template.css}" rel="stylesheet">
    <title>게시판</title>
</head>
<body>
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top" th:replace="fragments/common :: menu">
    <!--  <a class="navbar-brand" href="#">SUNShower</a>-->
    <!--  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">-->
    <!--    <span class="navbar-toggler-icon"></span>-->
    <!--  </button>-->

    <!--  <div class="collapse navbar-collapse" id="navbarsExampleDefault">-->
    <!--    <ul class="navbar-nav mr-auto">-->
    <!--      <li class="nav-item active">-->
    <!--        <a class="nav-link" href="#">홈 <span class="sr-only">(current)</span></a>-->
    <!--      </li>-->
    <!--      <li class="nav-item">-->
    <!--        <a class="nav-link" href="#">게시판</a>-->
    <!--&lt;!&ndash;      </li>&ndash;&gt;-->
    <!--&lt;!&ndash;      <li class="nav-item">&ndash;&gt;-->
    <!--&lt;!&ndash;&lt;!&ndash;        <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>&ndash;&gt;&ndash;&gt;-->
    <!--&lt;!&ndash;      </li>&ndash;&gt;-->
    <!--&lt;!&ndash;      <li class="nav-item dropdown">&ndash;&gt;-->
    <!--&lt;!&ndash;        <a class="nav-link dropdown-toggle" href="#" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>&ndash;&gt;-->
    <!--&lt;!&ndash;        <div class="dropdown-menu" aria-labelledby="dropdown01">&ndash;&gt;-->
    <!--&lt;!&ndash;          <a class="dropdown-item" href="#">Action</a>&ndash;&gt;-->
    <!--&lt;!&ndash;          <a class="dropdown-item" href="#">Another action</a>&ndash;&gt;-->
    <!--&lt;!&ndash;          <a class="dropdown-item" href="#">Something else here</a>&ndash;&gt;-->
    <!--&lt;!&ndash;        </div>&ndash;&gt;-->
    <!--&lt;!&ndash;      </li>&ndash;&gt;-->
    <!--    </ul>-->
    <!--&lt;!&ndash;    <form class="form-inline my-2 my-lg-0">&ndash;&gt;-->
    <!--&lt;!&ndash;      <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">&ndash;&gt;-->
    <!--&lt;!&ndash;      <button class="btn btn-secondary my-2 my-sm-0" type="submit">Search</button>&ndash;&gt;-->
    <!--&lt;!&ndash;    </form>&ndash;&gt;-->
    <!--  </div>-->
</nav>

<div class="container">
    <h2>게시판</h2>
</div>

<!-- Optional JavaScript; choose one of the two! -->
<!--Option 2: jQuery, Popper.js, and Bootstrap JS-->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js" integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s" crossorigin="anonymous"></script>

</body>
</html>

최종적으로 list.html은 위와같은 코드입니다.

 

 

 

 

정상적으로 실행되고 있음을 확인할 수 있습니다.

 

 

 

 

Head 태그 공통적인 부분 합치기 

common.html

 

<head th:fragment="head(title)">
<!-- 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" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<link href="starter-template.css" rel="stylesheet">
<title th:text="${title}">SUNShower</title>
</head>

common.html에 head 부분을 추가합니다.

※ 차이점 : head 부분의 타이틀명이 다릅니다. 이는 파라미터 단위로 받아 구현할 수 있습니다.

 

 

 

 

title이라는 파라미터로 정의를 하고, title 이름을 변경하며 차이나는 부분을 해결합니다.

※ th:fragment="타이틀명(파라미터명)"

th:text="${(파라미터명)}"

※ link 태그 안에 th:href 언어를 추가합니다.

 

 

 

 

list.html

 

list.html

<head th:replace="fragments/common :: 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" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
    <link href="starter-template.css" th:href="@{/starter-template.css}" rel="stylesheet">
    <title>게시판</title>
</head>

head 태그 안에 th:replace 언어를 추가합니다.

 

 

 

 

index.html

 

<head th:replace="fragments/common :: 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" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
  <link href="starter-template.css" rel="stylesheet">
  <title>SUNShower</title>
</head>

head 태그 안에 th:replace 언어를 추가합니다.

 

 

 

 

둘 다 정상적으로 작동되고 있음을 알 수 있습니다.

 

 

 

 

링크 연결하기

 

홈, 게시판 카테고리에 마우스 커서 위치 시 불 들어오게 하기

 

index.html

 

nav 태그 안에 menu 이름 옆에 파라미터로 home을 추가합니다.

 

 

 

list.html

 

nav 태그 안에 menu 이름 옆에 파라미터로 board를 추가합니다.

 

 

 

common.html

li 태그 안에 th:classappend 언어, span 태그 안에 th:if 언어를 추가합니다.

※ th:classappend="${(파라미터명)} == '(파라미터명)? 'active'

※ th:if="${(파라미터명)} == '파라미터명'

 

 

 

 

정상적으로 작동되고 있음을 확인할 수 있습니다.

 

 

링크 연결하기

<li class="nav-item" th:classappend="${menu} == 'home'? 'active'">
  <a class="nav-link" href="#" th:href="@{/}">홈 <span class="sr-only" th:if="${menu} == 'home'">(current)</span></a>
</li>
<li class="nav-item" th:classappend="${menu} == 'board'? 'active'">

a 태그 안에 th:href 언어를 추가합니다.

※ th:href="@{(경로)}"

 

 

 

 

클릭시 정상적으로 작동되고 있음을 확인할 수 있습니다.

 

 

 

 

최종코드

index.html

 

<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/common :: 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" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
  <link href="starter-template.css" rel="stylesheet">
  <title>SUNShower</title>
</head>
<body>
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top" th:replace="fragments/common :: menu('home')">
<!--  <a class="navbar-brand" href="#">SUNShower</a>-->
<!--  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">-->
<!--    <span class="navbar-toggler-icon"></span>-->
<!--  </button>-->

<!--  <div class="collapse navbar-collapse" id="navbarsExampleDefault">-->
<!--    <ul class="navbar-nav mr-auto">-->
<!--      <li class="nav-item active">-->
<!--        <a class="nav-link" href="#">홈 <span class="sr-only">(current)</span></a>-->
<!--      </li>-->
<!--      <li class="nav-item">-->
<!--        <a class="nav-link" href="#">게시판</a>-->
<!--&lt;!&ndash;      </li>&ndash;&gt;-->
<!--&lt;!&ndash;      <li class="nav-item">&ndash;&gt;-->
<!--&lt;!&ndash;&lt;!&ndash;        <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>&ndash;&gt;&ndash;&gt;-->
<!--&lt;!&ndash;      </li>&ndash;&gt;-->
<!--&lt;!&ndash;      <li class="nav-item dropdown">&ndash;&gt;-->
<!--&lt;!&ndash;        <a class="nav-link dropdown-toggle" href="#" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>&ndash;&gt;-->
<!--&lt;!&ndash;        <div class="dropdown-menu" aria-labelledby="dropdown01">&ndash;&gt;-->
<!--&lt;!&ndash;          <a class="dropdown-item" href="#">Action</a>&ndash;&gt;-->
<!--&lt;!&ndash;          <a class="dropdown-item" href="#">Another action</a>&ndash;&gt;-->
<!--&lt;!&ndash;          <a class="dropdown-item" href="#">Something else here</a>&ndash;&gt;-->
<!--&lt;!&ndash;        </div>&ndash;&gt;-->
<!--&lt;!&ndash;      </li>&ndash;&gt;-->
<!--    </ul>-->
<!--&lt;!&ndash;    <form class="form-inline my-2 my-lg-0">&ndash;&gt;-->
<!--&lt;!&ndash;      <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">&ndash;&gt;-->
<!--&lt;!&ndash;      <button class="btn btn-secondary my-2 my-sm-0" type="submit">Search</button>&ndash;&gt;-->
<!--&lt;!&ndash;    </form>&ndash;&gt;-->
<!--  </div>-->
</nav>

<main role="main" class="container">

  <div class="starter-template">
    <h1>Spring Boot Tutorial</h1>
    <p class="lead">Spring Boot를 이용해 웹 페이지 제작<br> Spring Security, JPA를 이용해 보안 설정과 데이터 다루기</p>
  </div>

</main>

<!-- Optional JavaScript; choose one of the two! -->
<!--Option 2: jQuery, Popper.js, and Bootstrap JS-->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js" integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s" crossorigin="anonymous"></script>

</body>
</html>

 

 

list.html
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/common :: 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" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
    <link href="starter-template.css" th:href="@{/starter-template.css}" rel="stylesheet">
    <title>게시판</title>
</head>
<body>
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top" th:replace="fragments/common :: menu('board')">
    <!--  <a class="navbar-brand" href="#">SUNShower</a>-->
    <!--  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">-->
    <!--    <span class="navbar-toggler-icon"></span>-->
    <!--  </button>-->

    <!--  <div class="collapse navbar-collapse" id="navbarsExampleDefault">-->
    <!--    <ul class="navbar-nav mr-auto">-->
    <!--      <li class="nav-item active">-->
    <!--        <a class="nav-link" href="#">홈 <span class="sr-only">(current)</span></a>-->
    <!--      </li>-->
    <!--      <li class="nav-item">-->
    <!--        <a class="nav-link" href="#">게시판</a>-->
    <!--&lt;!&ndash;      </li>&ndash;&gt;-->
    <!--&lt;!&ndash;      <li class="nav-item">&ndash;&gt;-->
    <!--&lt;!&ndash;&lt;!&ndash;        <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>&ndash;&gt;&ndash;&gt;-->
    <!--&lt;!&ndash;      </li>&ndash;&gt;-->
    <!--&lt;!&ndash;      <li class="nav-item dropdown">&ndash;&gt;-->
    <!--&lt;!&ndash;        <a class="nav-link dropdown-toggle" href="#" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>&ndash;&gt;-->
    <!--&lt;!&ndash;        <div class="dropdown-menu" aria-labelledby="dropdown01">&ndash;&gt;-->
    <!--&lt;!&ndash;          <a class="dropdown-item" href="#">Action</a>&ndash;&gt;-->
    <!--&lt;!&ndash;          <a class="dropdown-item" href="#">Another action</a>&ndash;&gt;-->
    <!--&lt;!&ndash;          <a class="dropdown-item" href="#">Something else here</a>&ndash;&gt;-->
    <!--&lt;!&ndash;        </div>&ndash;&gt;-->
    <!--&lt;!&ndash;      </li>&ndash;&gt;-->
    <!--    </ul>-->
    <!--&lt;!&ndash;    <form class="form-inline my-2 my-lg-0">&ndash;&gt;-->
    <!--&lt;!&ndash;      <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">&ndash;&gt;-->
    <!--&lt;!&ndash;      <button class="btn btn-secondary my-2 my-sm-0" type="submit">Search</button>&ndash;&gt;-->
    <!--&lt;!&ndash;    </form>&ndash;&gt;-->
    <!--  </div>-->
</nav>

<div class="container">
    <h2>게시판</h2>
</div>

<!-- Optional JavaScript; choose one of the two! -->
<!--Option 2: jQuery, Popper.js, and Bootstrap JS-->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js" integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s" crossorigin="anonymous"></script>

</body>
</html>

 

 

common.html
<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="head(title)">
<!-- 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" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<link href="starter-template.css" th:href="@{/starter-template.css}" rel="stylesheet">
<title th:text="${title}">SUNShower</title>
</head>
<body>

<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top" th:fragment="menu(menu)">
  <a class="navbar-brand" href="#">SUNShower</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarsExampleDefault">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item" th:classappend="${menu} == 'home'? 'active'">
        <a class="nav-link" href="#" th:href="@{/}">홈 <span class="sr-only" th:if="${menu} == 'home'">(current)</span></a>
      </li>
      <li class="nav-item" th:classappend="${menu} == 'board'? 'active'">
        <a class="nav-link" href="#" th:href="@{/board/list}">게시판<span class="sr-only" th:if="${menu} == 'board'">(current)</span></a>
        <!--      </li>-->
        <!--      <li class="nav-item">-->
        <!--&lt;!&ndash;        <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>&ndash;&gt;-->
        <!--      </li>-->
        <!--      <li class="nav-item dropdown">-->
        <!--        <a class="nav-link dropdown-toggle" href="#" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>-->
        <!--        <div class="dropdown-menu" aria-labelledby="dropdown01">-->
        <!--          <a class="dropdown-item" href="#">Action</a>-->
        <!--          <a class="dropdown-item" href="#">Another action</a>-->
        <!--          <a class="dropdown-item" href="#">Something else here</a>-->
        <!--        </div>-->
        <!--      </li>-->
    </ul>
    <!--    <form class="form-inline my-2 my-lg-0">-->
    <!--      <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">-->
    <!--      <button class="btn btn-secondary my-2 my-sm-0" type="submit">Search</button>-->
    <!--    </form>-->
  </div>
</nav>

</body>

</html>

 

 

 

참고자료

https://www.youtube.com/watch?v=WGIJ4CDUX44&list=PLPtc9qD1979DG675XufGs0-gBeb2mrona&index=5 

 

https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#including-template-fragments

 

Tutorial: Using Thymeleaf

1 Introducing Thymeleaf 1.1 What is Thymeleaf? Thymeleaf is a modern server-side Java template engine for both web and standalone environments, capable of processing HTML, XML, JavaScript, CSS and even plain text. The main goal of Thymeleaf is to provide a

www.thymeleaf.org