[Spring Boot] Thymeleaf(타임리프) layout dialect 사용하기

 

 

웹 페이지를 만들게되면 기본적으로 head, header, content, footer 등의 레이아웃으로 나누어서 만들게된다. 기존에 스프링과 jsp를 통하여 만들 때 tiles를 이용하여 각 영역들을 분할하여 작업할 수 있었는데, 타임리프에선 thymeleaf-layout-dialect를 이용하여 비스하게 사용할 수 있다.

 

 

타임리프는 프로젝트를 생성할 때 의존성을 추가하면 된다.

 

 

2021.08.13 - [Spring-Boot] - [Spring Boot] 프로젝트 생성하기(Intellij)

 

[Spring Boot] 프로젝트 생성하기(Intellij)

[Spring Boot] Spring Initializr를 이용하여 프로젝트 생성하기(Intellij) 기존에 STS(Spring Tool Suite)나 Eclipse 툴 안에서 Maven이나 Gradle로 프로젝트를 생성했던 경험이 있는데 Spring Initializr 웹 도..

dbsyys.tistory.com

 

기존에 프로젝트에 타임리프를 사용중이라면 의존성을 하나 더 추가하면 된다.

 

 

 

https://mvnrepository.com/

 

메이븐 사이트에 접속하여 "Thymeleaf layout dialect"를 검색한다.

 

 

검색 후 내용. 같은 이름이지만 2013년은 너무 오래전이니 2021년을 선택하자

 

 

Maven인지 Gradle인지는 각자 프로젝트 의존성 설정방식에 맞추면된다. 현재 프로젝트에서는 Gradle을 사용하고 있기때문에 Gradle을 사용한다.

 

 

implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
// https://mvnrepository.com/artifact/nz.net.ultraq.thymeleaf/thymeleaf-layout-dialect
implementation group: 'nz.net.ultraq.thymeleaf', name: 'thymeleaf-layout-dialect', version: '2.5.3'

 

해당 코드를 Gradle 의존성에 추가했다면 하나의 웹페이지를 구성할 영역들과 동적으로 바꿀 페이지를 지정하면 된다.

 

 

 

  • layout/head.html(영역으로 쓸 페이지)
  • layout/header.html(영역으로 쓸 페이지)
  • layout/navBar.html(영역으로 쓸 페이지)
  • layout/footer.html(영역으로 쓸 페이지)
  • layout/layout.html(각 영역들을 조합한 페이지)
  • main/content.html(각 영역을 유지하고 동적으로 변환할 페이지)
  • member/saveForm.html(각 영역을 유지하고 동적으로 변환할 페이지)

 

 

- layout/layout.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
    <head th:replace="layout/head :: layout_head(~{::meta}, ~{::title}, ~{::link})">
    </head>
    <body class="nav-md">
        <div class="container body">
            <div class="main_container">

                <div th:replace="~{layout/navBar :: layout_navBar}"></div>
                <div th:replace="~{layout/header :: layout_header}"></div>
                <div layout:fragment="layout_content"></div>
<!--                <div th:replace="~{layout/content :: layout_content}"></div>-->
                <div th:replace="~{layout/footer :: layout_footer}"></div>

            </div>
        </div>

    </body>
</html>

 

기본적으로 타임리프를 쓰기위해선 xmlns:th="http://www.thymeleaf.org" 설정을 해야하며 layout-dialect를 사용하는 페이지에선 xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"를 설정한다.

 

각 영역들을 지정할 땐 th:replace로 경로를 지정하며, 주된 content부분의 내용은 페이지마다 동적으로 변환할 것이기 때문에  layout:fragment를 지정한다. 또한 <head> 부분은 head.html 페이지에서 설정한 정보를 받기위하여 meta, title, link 요소를 파라미터로 받아오게 설정했다.

 

 

- layout/head.html

<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="layout_head(meta, title, link)">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <!-- Meta, title, CSS, favicons, etc. -->
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" th:href="@{/images/favicon.ico}" type="image/ico" />

    <title>Gentelella Alela! | </title>

    <!-- Bootstrap -->
    <link th:href="@{/vendors/bootstrap/dist/css/bootstrap.min.css}" rel="stylesheet">
    <!-- Font Awesome -->
    <link th:href="@{/vendors/font-awesome/css/font-awesome.min.css}" rel="stylesheet">
    <!-- NProgress -->
    <link th:href="@{/vendors/nprogress/nprogress.css}" rel="stylesheet">
    <!-- iCheck -->
    <link th:href="@{/vendors/iCheck/skins/flat/green.css}" rel="stylesheet">
    .
    .
    .
    .

 

head부분은 <head>태그의 모든 설정부분을 그대로 넘기기 위해서 meta, title, link등 의 요소를 파라미터로 넘겼다. 현재 설정한 페이지의 요소들이 layout.html 파일의 내용으로 변경된다.

 

 

- layout/header.html

<html xmlns:th="http://www.thymeleaf.org">
    <th:block th:fragment="layout_header">
        <!-- top navigation -->
            <div class="top_nav">
                <div class="nav_menu">
                    <div class="nav toggle">
                        <a id="menu_toggle"><i class="fa fa-bars"></i></a>
                    </div>
                    .
                    .
                    .
                    .

 

 

- layout/navBar.html

<html xmlns:th="http://www.thymeleaf.org">
    <th:block th:fragment="layout_navBar">
        <div class="col-md-3 left_col">
            <div class="left_col scroll-view">
                <div class="navbar nav_title" style="border: 0;">
                    <a href="index.html" class="site_title"><i class="fa fa-paw"></i> <span>Gentelella Alela!</span></a>
                </div>

                <div class="clearfix"></div>
                .
                .
                .
                .

 

 

- layout/footer.html

<html xmlns:th="http://www.thymeleaf.org">
    <th:block th:fragment="layout_footer">
        <!-- footer content -->
            <footer>
                <div class="pull-right">
                    Gentelella - Bootstrap Admin Template by <a href="https://colorlib.com">Colorlib</a>
                </div>
                <div class="clearfix"></div>
            </footer>
        <!-- /footer content -->
    </th:block>
</html>

 

layout.html 페이지에서 영역으로 쓰일 부분은 th:replace, 각 영역에 해당하는 페이지는 th:fragment로 지정하며 두 부분의 이름은 같아야 한다.

 

 

- main/content.html

<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorator="layout/layout">
    <th:block layout:fragment="layout_content">
        <!-- page content -->
            <div class="right_col" role="main">
                <!-- top tiles -->
                <div class="row" style="display: inline-block;" >
                    <div class="tile_count">
                        <div class="col-md-2 col-sm-4  tile_stats_count">
                            <span class="count_top"><i class="fa fa-user"></i> Total Users</span>
                            <div class="count">2500</div>
                            <span class="count_bottom"><i class="green">4% </i> From last Week</span>
                        </div>
                        .
                        .
                        .
                        .
                        .

 

layout.html 에서 동적으로 변경시킬 content가 들어갈 페이지 이기때문에 html 부분에 xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" 설정을 한다. 추가적으로 해당 페이지에서는 어떤 페이지의 fragment로 쓸지 알아야하기 때문에 layout:decorator 설정을하고 layout으로 쓸 페이지의 경로를 지정해준다.

 

해당 페이지는 페이지 레이아웃은 유지하면서 상황에따라 content 부분만 바꿀 것이기 때문에 위에서 지정했던 영역들과는 다르게 th:fragment가 아닌 layout:fragment로 설정한다. 마찬가지로 layout.html에서 지정했던 name과 동일하게 지정한다.

 

 

- member/saveForm.html

<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorator="layout/layout">
    <th:block layout:fragment="layout_content">

    </th:block>
</html>

 

해당 페이지에도 content.html과 같은 설정을 했다. layout.html 페이지를 레이아웃으로 유지하면서 content 부분을 content.html과 saveForm.html 부분을 동적으로 변환하며 사용할 수 있다. 이러한 설정을 통해 다른 페이지를 추가했을 때도 같은 레이아웃을 적용할 수 있다.

+ Recent posts