오봉이와 함께하는 개발 블로그

스프링 MVC 2 - 템플릿 레이아웃 본문

BE/Thymeleaf

스프링 MVC 2 - 템플릿 레이아웃

오봉봉이 2022. 8. 17. 02:26
728x90

템플릿 레이아웃 1

템플릿 조각은 일부 코드 조각을 가지고와서 사용했다면, 이번에는 개념을 더 확장해서 코드 조각을 레이아웃에 넘겨서 사용하는 방법이다.

예를 들어 <head> 태그 안에 공통으로 사용하는 css, javascript같은 정보들이 있는데, 이런 정보들을 한 곳에 모아두고 공통으로 사용하지만, 각 페이지마다 필요한 정보를 더 추가해서 사용하고 싶을 때 사용한다.

코드

@GetMapping("/layout")
public String layout() {
    return "template/layout/layoutMain";
}

/resources/templates/template/layout/layoutMain.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
    <head th:replace="template/layout/base :: common_header(~{::title},~{::link})">
        <title>메인 타이틀</title>
        <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
        <link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}">
    </head>
    <body>
        메인 컨텐츠
    </body>
</html>

/resources/templates/template/layout/base.html

<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="common_header(title,links)">

    <title th:replace="${title}">레이아웃 타이틀</title>

    <!-- 공통 -->
    <link rel="stylesheet" type="text/css" media="all" th:href="@{/css/awesomeapp.css}">
    <link rel="shortcut icon" th:href="@{/images/favicon.ico}">
    <script type="text/javascript" th:src="@{/sh/scripts/codebase.js}"></script>

    <!-- 추가 -->
    <th:block th:replace="${links}" />

</head>

결과

<!DOCTYPE html>
<html>
    <head>
        <title>메인 타이틀</title>
        <!-- 공통 -->
        <link rel="stylesheet" type="text/css" media="all" href="/css/awesomeapp.css">
        <link rel="shortcut icon" href="/images/favicon.ico">
        <script type="text/javascript" src="/sh/scripts/codebase.js"></script>
        <!-- 추가 -->
        <link rel="stylesheet" href="/css/bootstrap.min.css">
        <link rel="stylesheet" href="/themes/smoothness/jquery-ui.css">
    </head>
    <body>
        메인 컨텐츠
    </body>
</html>

common_header(~{::title},~{::link})가 핵심이다.
::title은 현재 페이지의 <title> 태그들을 전달한다.
::link는 현재 페이지의 <link> 태그들을 전달한다.

layoutMain.html<head th:replace>를 사용했기 때문에 자기의 <head>를 사용하지 않고 template/layout/base :: common_header즉, base.html<head>로 대체된다.

::title::link를 통해 자기의 <title><link>태그를 모두 base.html로 넘긴다.

<title th:replace="${title}">레이아웃 타이틀</title>를 대체해서 <title>메인 타이틀</title>가 되고, <th:block th:replace="${links}" />를 대체해서
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
<link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}">가 입력되어 layoutMain.html<head>로 대체된다.


템플릿 레이아웃2

<html>전체에 적용할 수도 있다.

코드

@GetMapping("/layoutExtend")
public String layoutExtends() {
    return "template/layoutExtend/layoutExtendMain";
}

/resources/templates/template/layoutExtend/layoutExtendMain.html

<!DOCTYPE html>
<html th:replace="~{template/layoutExtend/layoutFile :: layout(~{::title}, ~{::section})}" xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>메인 페이지 타이틀</title>
    </head>
    <body>
        <section>
            <p>메인 페이지 컨텐츠</p>
            <div>메인 페이지 포함 내용</div>
        </section>
    </body>
</html>

/resources/templates/template/layoutExtend/layoutFile.html

<!DOCTYPE html>
<html th:fragment="layout (title, content)" xmlns:th="http://www.thymeleaf.org">
    <head>
        <title th:replace="${title}">레이아웃 타이틀</title>
    </head>
    <body>
        <h1>레이아웃 H1</h1>
        <div th:replace="${content}">
            <p>레이아웃 컨텐츠</p>
        </div>
        <footer>
            레이아웃 푸터
        </footer>
    </body>
</html>

결과

<!DOCTYPE html>
<html>
    <head>
        <title>메인 페이지 타이틀</title> </head>
    <body>
        <h1>레이아웃 H1</h1>
        <section>
            <p>메인 페이지 컨텐츠</p>
            <div>메인 페이지 포함 내용</div>
        </section>
        <footer>
            레이아웃 푸터
        </footer>
    </body>
</html>

layoutExtendMain.html
th:replace="~{template/layoutExtend/layoutFile :: layout(~{::title}, ~{::section})}"를 해서 ~{::title}~{::section}을 넘겼다.

layoutFile.htmlth:fragment="layout (title, content)"를 통해
<title th:replace="${title}">레이아웃 타이틀</title><div th:replace="${content}">에 받았다

layoutFile.html<title>태그 내용이 layoutExtendMain.html<title>로 대체되었고, 마찬가지로 layoutFile.html<div>태그 내용이 layoutExtendMain.html<section>태그의 내용으로 대체되어 layoutExtendMain.html에 넘어가서 렌더링 되었다.

출처 : 인프런 김영한 지식공유자님 강의 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
728x90
Comments