본문 바로가기
벡엔드/spring

[Spring boot] Layout Dialect로 공통 레이아웃 쉽게 구성하기 (Spring Boot + Thymeleaf)

by Alan__kang__morlang 2025. 5. 30.
반응형
Layout Dialect로 공통 레이아웃 쉽게 구성하기 (Spring Boot + Thymeleaf)

 

이 글은 JSP 기반 레거시 프로젝트를 Spring Boot + Thymeleaf로 전환하면서 Layout Dialect를 활용해 레이아웃과 공통 템플릿을 구성하는 방법을 단계별로 설명합니다.

1️⃣ pom.xml 의존성 추가

Spring Boot 3.5.0 기준으로 thymeleaf-layout-dialect를 추가합니다.

<dependency>
    <groupId>nz.net.ultraq.thymeleaf</groupId>
    <artifactId>thymeleaf-layout-dialect</artifactId>
    <version>3.2.1</version>
</dependency>

2️⃣ 프로젝트 폴더 구조

프로젝트에서 정적 리소스와 템플릿은 아래처럼 구성합니다.

src/
 └── main/
      └── resources/
           ├── static/              (CSS, JS, 이미지)
           │   ├── css/
           │   ├── js/
           │   └── images/
           ├── templates/           (Thymeleaf 템플릿)
           │   ├── layout.html      (레이아웃 템플릿)
           │   ├── fragments/
           │   │   ├── head.html    (공통 head)
           │   │   └── navigation.html (공통 메뉴)
           │   └── recipe/
           │       └── recipeForm.html (페이지 내용)
           └── application.yml

3️⃣ layout.html 작성 (레이아웃 템플릿)

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
    <title layout:title-pattern="$DECORATOR_TITLE - My Site">My Site</title>
    <th:block th:replace="fragments/head :: commonHead"></th:block>
</head>
<body>
    <header th:replace="fragments/navigation :: navigation"></header>
    <main layout:fragment="content"></main>
</body>
</html>

4️⃣ 공통 head (fragments/head.html)

<th:block th:fragment="commonHead">
    <link rel="stylesheet" th:href="@{/css/style.css}">
    <script th:src="@{/js/jquery.min.js}"></script>
</th:block>

5️⃣ 공통 메뉴 (fragments/navigation.html)

<nav th:fragment="navigation">
    <ul>
        <li><a th:href="@{ / }"></a></li>
        <li><a th:href="@{ /recipe/recipeBoardWrite }">레시피 등록</a></li>
    </ul>
</nav>

6️⃣ 개별 페이지 (recipeForm.html)

<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layout}">
<head>
    <title layout:title="레시피 등록">레시피 등록</title>
</head>
<body layout:fragment="content">
    <h2>레시피 등록 페이지</h2>
    <form th:action="@{ /recipe/recipeBoardWrite }" method="post">
        <input type="text" name="recipeName" placeholder="레시피명">
    </form>
</body>
</html>

7️⃣ 정적 리소스 위치

CSS, JS, 이미지 등은 src/main/resources/static에 두고 th:href, th:src로 연결합니다.

8️⃣ 레이아웃 적용 결과

  • layout.html의 <main layout:fragment="content">에 recipeForm.html의 body 내용이 삽입됩니다.
  • 공통 head, 메뉴는 th:replace로 포함되어 유지보수가 쉬워집니다.
  • 각 페이지는 layout:decorate="~{layout}"로 공통 레이아웃을 상속받습니다.

반응형