[Thymeleaf] 템플릿조각 사용법

HSRyuuu dev blog·2023년 4월 1일
0

타임리프(Thymeleaf)

목록 보기
7/9

웹 페이지를 개발할 때 계속 반복되는 공통영역들이 많이 생기게 된다.
이런 부분을 따로 떼어서 하나의 파일로 만들어서,
마치 자바에서 메소드를 불러오듯이 불러서 사용할 수 있다.

  • 템플릿 조각은 th:fragment 으로 지정하고
  • 불러올 때는 th:insert="~{ (경로) :: (fragment이름) } 으로 불러온다.
    (insert 대신 replace를 사용하여, 삽입이 아닌 교체를 할수도 있다. )

1. 템플릿 조각

예제에 사용할 템플릿 조각

template/fragment/footer.html 경로와 이름을 가진 html 파일이 있다.

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

<footer th:fragment="copy">
    푸터 자리 입니다.
</footer>

<footer th:fragment="copyParam (param1, param2)">
    <p>파라미터 자리 입니다.</p>
    <p th:text="${param1}"></p>
    <p th:text="${param2}"></p>
</footer>

</body>
</html>

1) 삽입 th:insert

  • 기존 태그 내에 템플릿 조각을 불러온다.
  • 아래 예제에서는 <div> 태그 내에 footer.html의 th:fragment="copy"로 지정된 부분을 불러온다.
<div th:insert="~{template/fragment/footer :: copy}"></div>

(페이지 소스보기)

<div><footer>
    푸터 자리 입니다.
</footer></div>

2) 교체 th:replace

  • 기존 태그를 탬플릿 조각으로 교체한다.
  • 아래 예제에서는 <div> 태그 자체를 footer.html의 th:fragment="copy"교체한다.
<div th:replace="~{template/fragment/footer :: copy}"></div>

(코드가 단순한 경우에는 아래와 같이 쓸 수 있다.)

<div th:replace="template/fragment/footer :: copy"></div>

(페이지 소스보기)

  • <div> 태그가 없어지고, <footer>태그로 교체되었다.
<footer>
    푸터 자리 입니다.
</footer>

3) 파라미터 사용

(footer.html)의 일부

<footer th:fragment="copyParam (param1, param2)">
    <p>파라미터 자리 입니다.</p>
    <p th:text="${param1}"></p>
    <p th:text="${param2}"></p>
</footer>
  • 아래 예제에서 ‘데이터1’ , ‘데이터2’ 를 파라미터로 copyParam으로 넘긴다.
  • 아래 예제에서 받은 파라미터를 footer.html의 param1, param2에 대입하고,
    아래의 <div>태그를 footer.html의 th:fragment="copyParam (param1, param2)"으로 교체한다.
<div th:replace="~{template/fragment/footer :: copyParam ('데이터1', '데이터2')}"></div>

(페이지 소스보기)

<footer>
    <p>파라미터 자리 입니다.</p>
    <p>데이터1</p>
    <p>데이터2</p>
</footer>



2. 템플릿 레이아웃

템플릿 레이아웃을 이용하면, <head>, <html>와 같이 큼직한 부분을 전부 대체할 수도 있다.

레이아웃 파일을 따로 만들어서 Main에서 일부사용하고,
일부는 레이아웃 파일의 내용으로 그대로 교체할 수 있다.

<head>를 전부 대체하는 예제, <html> 전체를 대체하는 예제를 통해 알아보자.


1) <head>를 변경하는 예제

(1) 레이아웃 페이지 (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>

(2) main 페이지 (layoutMain.html)

th:replace -> main페이지의 헤더 자체를 /base의 common_header로 교체한다.

이 때,
th:fragment="common_header(title,links)"
common_header(~{::title},~{::link})가 대응한다.

<!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>
  1. <title> 태그
  • main의 “메인 타이틀” 을 받아서 base의 ${title} 에 대입한다.
  • base의 <title>태그의 "레이아웃 타이틀"${title}로 받은 “메인 타이틀”로 교체된다.
  1. <link> 태그
  • main의 <link>들이 base의 <link>들로 교체되어 출력된다.
  1. <script> 태그
  • main에는<script>가 없다.
  • 그러나 <head> 자체를 바꾸기 때문에 base의 <script>가 추가된다.
  1. th:block 부분 추가
  • main -> th:replace ... ~{::link}로 main의 <link>들이 모두 base의 th:fragment...links에 대입된다.
  • main의 <link>들을 모두 받아서 그대로 출력한다.

(3)출력

<!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>

2) <html>을 전부 변경하는 예제

(1) 레이아웃 페이지 (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>

(2) main 페이지 (layoutExtendMain.html)

  • main 페이지의 html 전부를 layoutFile.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>
  1. <title>
  • main의 <title>을 받아서 layoutFile<title>을 대체한다.
  1. <h1>
  • main에는 <h1>이 없다.
  • 따라서 layoutFile<h1>을 그대로 출력한다.
  1. <section>
  • layoutFilecontent 자리에 main의 ~{::section}이 대입된다.
  • main의 section을 받아서, layoutFile<div th:replace="${content}">를 대체한다.
  1. <footer>
  • main에는 <footer>가 없다.
  • 따라서 layoutFile<footer>를 그대로 출력한다.

(3) 출력

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

(참고)김영한님 인프런 Spring MVC-2
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2

profile
Exciting dev life / 댓글, 피드백, 질문 환영합니다 !!!

0개의 댓글