헤르메스 LIFE

[Spring Boot] Spring Boot + Thymeleaf + Thymeleaf Layout Dialect 본문

Spring Boot Framework

[Spring Boot] Spring Boot + Thymeleaf + Thymeleaf Layout Dialect

헤르메스의날개 2022. 3. 10. 00:46
728x90

springboot.z01
15.00MB
springboot.z02
15.00MB
springboot.zip
5.63MB

개발환경

1. STS 버전 : 4.13.1

2. JDK 버전 : OpenJDK 11.0.14_9_x64

3. Tomcat 버전 : 9.0.56

4. Maven 버전 : 3.8.4

5. Spring 버전 : Spring Boot 2.6.3

6. Database : Docker 에 DB 설치

- primary - PostgreSQL 13.3

7. Spring Security : 5.6.1

8. lombok

9. Thymeleaf 3.0.14

   Thymeleaf Layout Dialect 3.0.0


목표

Spring Boot 기반의 Thymeleaf 를 이용한 Layout Dialect 화면 개발


pom.xml 에 Thymeleaf Layout Dialect Dependency 추가합니다.

        <!-- Thymeleaf -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>nz.net.ultraq.thymeleaf</groupId>
            <artifactId>thymeleaf-layout-dialect</artifactId>
        </dependency>

application.yml 에서 JSP 관련 설정을 막고, Thymeleaf 설정을 추가합니다.

spring:
  thymeleaf:
    cache: false
    
# JSP 설정을 막음.
#  mvc:
#    view:
#      prefix: /WEB-INF/jsp/                                   # View Resolver setting
#      suffix: .jsp

index.html -> layout:decorate="~{/layouts/layout}" 에 주의하시기 바랍니다.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{/layouts/layout}">

<th:block layout:fragment="content">
    <!-- Begin Page Content -->
    <div class="container-fluid">
        <h1>레이아웃을 사용해 페이지 구성하기!</h1>
    </div>
</th:block>
</html>

layout.html

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">

<!-- 공통 헤드-->
<th:block th:replace="/layouts/fragments/head :: headFragment"></th:block>

<body id="page-top" class="dashboard dashboard_1">
    <div class="full_container">
        <div class="inner_container">
            <!-- 사이드바-->
            <th:block th:replace="/layouts/fragments/sidebar :: sidebarFragment"></th:block>
            <!-- right content -->
            <div id="content">
                <!-- 상단바-->
                <th:block th:replace="/layouts/fragments/top :: topbarFragment"></th:block>
                <!-- dashboard inner -->
                <div class="midde_cont">
                    <div class="container-fluid">
                        <th:block layout:fragment="content"></th:block>
                    </div>
                </div>
                <!-- 공통 하단-->
                <th:block th:replace="/layouts/fragments/footer :: footerFragment"></th:block>
            </div>
            <!-- end dashboard inner -->
        </div>
    </div>
    </div>
    <!-- 공통 스크립트-->
    <th:block th:replace="/layouts/fragments/script :: scriptFragment"></th:block>
</body>
</html>

head.html

<!DOCTYPE html>
<html lagn="ko" xmlns:th="http://www.thymeleaf.org">
<!-- Head -->
<th:block th:fragment="headFragment">
	<head>
        <!-- basic -->
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <!-- mobile metas -->
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="viewport" content="initial-scale=1, maximum-scale=1">
        <!-- site metas -->
        <title>Pluto - Responsive Bootstrap Admin Panel Templates</title>
        <meta name="keywords" content="">
        <meta name="description" content="">
        <meta name="author" content="">
        <!-- site icon -->
        <link rel="icon" href="images/fevicon.png" type="image/png" />
        <!-- bootstrap css -->
        <link rel="stylesheet" href="css/bootstrap.min.css" />
        <!-- site css -->
        <link rel="stylesheet" href="css/style.css" />
        <!-- responsive css -->
        <link rel="stylesheet" href="css/responsive.css" />
        <!-- select bootstrap -->
        <link rel="stylesheet" href="css/bootstrap-select.css" />
        <!-- scrollbar css -->
        <link rel="stylesheet" href="css/perfect-scrollbar.css" />
        <!-- custom css -->
        <link rel="stylesheet" href="css/custom.css" />
        <!--[if lt IE 9]>
        <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
        <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
        <![endif]-->
	</head>
</th:block>
</html>

sidebar.html

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">

<th:block th:fragment="sidebarFragment">
            <!-- Sidebar  -->
            <nav id="sidebar">
               <div class="sidebar_blog_1">
                  <div class="sidebar-header">
                     <div class="logo_section">
                        <a href="index.html"><img class="logo_icon img-responsive" src="/images/logo/logo_icon.png" alt="#" /></a>
                     </div>
                  </div>
                  <div class="sidebar_user_info">
                     <div class="icon_setting"></div>
                     <div class="user_profle_side">
                        <div class="user_img"><img class="img-responsive" src="/images/layout_img/user_img.jpg" alt="#" /></div>
                        <div class="user_info">
                           <h6>John David</h6>
                           <p><span class="online_animation"></span> Online</p>
                        </div>
                     </div>
                  </div>
               </div>
               <div class="sidebar_blog_2">
                  <h4>General</h4>
                  <ul class="list-unstyled components">
                     <li class="active">
                        <a href="#dashboard" data-toggle="collapse" aria-expanded="false" class="dropdown-toggle"><i class="fa fa-dashboard yellow_color"></i> <span>Dashboard</span></a>
                        <ul class="collapse list-unstyled" id="dashboard">
                           <li>
                              <a href="dashboard.html">> <span>Default Dashboard</span></a>
                           </li>
                           <li>
                              <a href="dashboard_2.html">> <span>Dashboard style 2</span></a>
                           </li>
                        </ul>
                     </li>
                     <li><a href="widgets.html"><i class="fa fa-clock-o orange_color"></i> <span>Widgets</span></a></li>
                     <li>
                        <a href="#element" data-toggle="collapse" aria-expanded="false" class="dropdown-toggle"><i class="fa fa-diamond purple_color"></i> <span>Elements</span></a>
                        <ul class="collapse list-unstyled" id="element">
                           <li><a href="general_elements.html">> <span>General Elements</span></a></li>
                           <li><a href="media_gallery.html">> <span>Media Gallery</span></a></li>
                           <li><a href="icons.html">> <span>Icons</span></a></li>
                           <li><a href="invoice.html">> <span>Invoice</span></a></li>
                        </ul>
                     </li>
                     <li><a href="tables.html"><i class="fa fa-table purple_color2"></i> <span>Tables</span></a></li>
                     <li>
                        <a href="#apps" data-toggle="collapse" aria-expanded="false" class="dropdown-toggle"><i class="fa fa-object-group blue2_color"></i> <span>Apps</span></a>
                        <ul class="collapse list-unstyled" id="apps">
                           <li><a href="email.html">> <span>Email</span></a></li>
                           <li><a href="calendar.html">> <span>Calendar</span></a></li>
                           <li><a href="media_gallery.html">> <span>Media Gallery</span></a></li>
                        </ul>
                     </li>
                     <li><a href="price.html"><i class="fa fa-briefcase blue1_color"></i> <span>Pricing Tables</span></a></li>
                     <li>
                        <a href="contact.html">
                        <i class="fa fa-paper-plane red_color"></i> <span>Contact</span></a>
                     </li>
                     <li class="active">
                        <a href="#additional_page" data-toggle="collapse" aria-expanded="false" class="dropdown-toggle"><i class="fa fa-clone yellow_color"></i> <span>Additional Pages</span></a>
                        <ul class="collapse list-unstyled" id="additional_page">
                           <li>
                              <a href="profile.html">> <span>Profile</span></a>
                           </li>
                           <li>
                              <a href="project.html">> <span>Projects</span></a>
                           </li>
                           <li>
                              <a href="login.html">> <span>Login</span></a>
                           </li>
                           <li>
                              <a href="404_error.html">> <span>404 Error</span></a>
                           </li>
                        </ul>
                     </li>
                     <li><a href="map.html"><i class="fa fa-map purple_color2"></i> <span>Map</span></a></li>
                     <li><a href="charts.html"><i class="fa fa-bar-chart-o green_color"></i> <span>Charts</span></a></li>
                     <li><a href="settings.html"><i class="fa fa-cog yellow_color"></i> <span>Settings</span></a></li>
                  </ul>
               </div>
            </nav>
            <!-- end sidebar -->
</th:block>

</html>

top.html

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml">

<th:block th:fragment="topbarFragment">
                <!-- topbar -->
                <div class="topbar">
                   <nav class="navbar navbar-expand-lg navbar-light">
                      <div class="full">
                         <button type="button" id="sidebarCollapse" class="sidebar_toggle"><i class="fa fa-bars"></i></button>
                         <div class="logo_section">
                            <a href="index.html"><img class="img-responsive" src="images/logo/logo.png" alt="#" /></a>
                         </div>
                         <div class="right_topbar">
                            <div class="icon_info">
                               <ul>
                                  <li><a href="#"><i class="fa fa-bell-o"></i><span class="badge">2</span></a></li>
                                  <li><a href="#"><i class="fa fa-question-circle"></i></a></li>
                                  <li><a href="#"><i class="fa fa-envelope-o"></i><span class="badge">3</span></a></li>
                               </ul>
                               <ul class="user_profile_dd">
                                  <li>
                                     <a class="dropdown-toggle" data-toggle="dropdown"><img class="img-responsive rounded-circle" src="images/layout_img/user_img.jpg" alt="#" /><span class="name_user">John David</span></a>
                                     <div class="dropdown-menu">
                                        <a class="dropdown-item" href="profile.html">My Profile</a>
                                        <a class="dropdown-item" href="settings.html">Settings</a>
                                        <a class="dropdown-item" href="help.html">Help</a>
                                        <a class="dropdown-item" href="#"><span>Log Out</span> <i class="fa fa-sign-out"></i></a>
                                     </div>
                                  </li>
                               </ul>
                            </div>
                         </div>
                      </div>
                   </nav>
                </div>
                <!-- end topbar -->
</th:block>
</html>

footer.html

<!DOCTYPE html>
<html lagn="ko" xmlns:th="http://www.thymeleaf.org">

<!-- Footer -->
<th:block th:fragment="footerFragment">
                  <!-- footer -->
                  <div class="container-fluid">
                     <div class="footer">
                        <p>Copyright © 2018 Designed by html.design. All rights reserved.<br><br>
                           Distributed By: <a href="https://themewagon.com/">ThemeWagon</a>
                        </p>
                     </div>
                  </div>
</th:block>

</html>

script.html

<!DOCTYPE html>
<html lagn="ko" xmlns:th="http://www.thymeleaf.org">

<!-- 공통으로 쓰이는 script 파일을넣는다.-->
<th:block th:fragment="scriptFragment">
      <!-- jQuery -->
      <script src="/js/jquery.min.js"></script>
      <script src="/js/popper.min.js"></script>
      <script src="/js/bootstrap.min.js"></script>
      <!-- wow animation -->
      <script src="/js/animate.js"></script>
      <!-- select country -->
      <script src="/js/bootstrap-select.js"></script>
      <!-- owl carousel -->
      <script src="/js/owl.carousel.js"></script> 
      <!-- chart js -->
      <script src="/js/Chart.min.js"></script>
      <script src="/js/Chart.bundle.min.js"></script>
      <script src="/js/utils.js"></script>
      <script src="/js/analyser.js"></script>
      <!-- nice scrollbar -->
      <script src="/js/perfect-scrollbar.min.js"></script>
      <script>
         var ps = new PerfectScrollbar('#sidebar');
      </script>
      <!-- custom js-->
      <script src="/js/custom.js"></script>
 <!-- 
      <script src="/js/chart_custom_style1.js"></script>
 -->
</th:block>
</html>

오픈소스화면입니다. ( 출처는 아래 Free Admin Template 사이트 입니다. )


Thymeleaf Layout Dialect 에서 layout:decorator 가 제대로 작동되지 않는 오류

https://hermeslog.tistory.com/590

 

[Thyemleaf] Thymeleaf Layout Dialect 에서 layout:decorator 가 제대로 작동되지 않는 오류

layout:decorator 를 아무리 찾아봐도, 최근 소스를 참조해도.. 전부 layout:decorator 를 사용하더군요.. ^^;; layout:decorator -> layout:decorate 로 변경된 듯 합니다. <!DOCTYPE html> 레이아웃을 사용해 페..

hermeslog.tistory.com


참고

https://dev-jwblog.tistory.com/34

 

[SpringBoot] thymeleaf-layout-dialect 적용하기

이전 글에서 bootstrap 템플릿을 사용해서 페이지를 구성하였다. 하지만, 페이지마다 공통으로 사용하는 부분(사이드바, footer 등)에 대해서 찾아서 복사하며 개발하기는 시간이 오래걸린다. 그래

dev-jwblog.tistory.com

https://themewagon.com/theme-category/admin-dashboard/

 

Free & Premium HTML5 CSS3 Admin Templates | Responsive Dashboard

Searching for free or premium HTML5 dashboard templates? Download responsive HTML5 CSS3 Admin Dashboard Templates. Free for personal and commercial use.

themewagon.com

 

728x90