본문 바로가기
이론/Spring

[Spring Boot 템플릿 엔진] 타임리프(Thymeleaf) 공통 템플릿 재사용

by 6161990 2021. 7. 9.

 

 

 

반복적으로 사용되는 템플릿을 공통사항으로 만들어 재사용하는 방법이 있다. JSP에서는 include와 똑같은 원리라고 보면된다. 

 

 

 

공통 템플릿으로 재사용하는 2가지 방법

 

1. 템플릿 프래그먼트 : 여러 템플릿을 작성할 때, 여러 템플릿에서 같은 내용이 사용되는 경우가 많다. 이러한 경우에는 그러한 공통적인 내용을 별도 파일로 추출하고 싶을 때 프래그먼트를 사용한다.

 

2.템플릿 레이아웃 : 여러 템플릿에서 같은 디자인 레이아웃을 적용하는 일반적으로 공통적인 레이아웃을 정의하고 공유하게 된다. 이럴 때 유효한 라이브러리로 타임리프 레이아웃 다이얼렉트가 있다. 

 

 

 

 

1. 템플릿 프래그먼트  fragment ; 부서진 조각

템플릿의 일부를 분활해서 별도 파일로 꺼낼 수 있다. 헤더, 푸터, 메뉴가 프래그먼트가 자주 이용되지만 특정 UI 컴포넌트를 프래그먼트로 꺼내는 것도 가능하다. 프래그먼트를 이용하려면 먼저 기본 정의된 프래그먼트가 있어야하고 그에대한 참조가 있어야한다. 

 

 

프래그먼트를 정의하는 두 가지 방법

  • 타임리프의 th:fragment
  • CSS 셀렉터와 마찬가지로 id 속성을 이용한 프래그먼트 정의
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">

   <body>

      <footer th:fragment="footerA">
          푸터 A 입니다
      </footer>


      <footer id="footerB">
          푸터 B 입니다
      </footer>

  </body>
</html>

 

 

정의된 프래그먼트를 참조하는 두 가지 방법

  • 타임리프의 th:include 속성을 이용한 프래그먼트의 인클루드
  • 타임리프의 th:replace 속성을 이용한 프래그먼트의 대체

 

 

 th:include

 

	<h2>템플릿 프래그먼트 A(th:include + frag)</h2>
	<div th:include="footer :: footerA"></div>

	<h2>템플릿 프래그먼트 A(th:include + id)</h2>
	<div th:include="footer :: #footerB"></div>
<h2>템플릿 프래그먼트 A(th:include + frag)</h2>
<div>
          푸터 A 입니다
</div>


<h2>템플릿 프래그먼트 A(th:include + id)</h2>
<div>
          푸터 B 입니다
</div>

 

 

 

 

 

th:include와 th:replace의 차이

 

프래그먼트를 참조해서 대체하는 경우 th:replace 속성을 이용한다. 속성 값을 지정하는 방법은 include와 같다.

th:replace를 이용한 경우, th:replace 속성을 부여한 요소에서 프래그먼트의 내용으로 대체된다.

=> <div> 요소에서 <footer>요소로 대체

 

	<h2>th:include와 th:replace의 차이</h2>
	<div th:include="footer :: footerA"></div>
	<div th:replace="footer :: footerA"></div>
	<h2>th:include와 th:replace의 차이</h2>
	<div>
		푸터 A 입니다
	</div>
	
	<footer>
		푸터 A 입니다
	</footer>

 

 

 

 

2. 템플릿 레이아웃  

 

타임리프 레이아웃 다이얼렉트 설정

pom.xml 설정

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

 

 

 

타임리프 레이아웃 다이얼렉트에 의한 뷰 구현

타임리프 레이아웃 다이얼렉트는 공통 레이아웃이 되는 템플릿을 'Decorator'라고 하며, 공통 레이아웃을 적용하는 측의 개별 템플릿을 'Fragment'라 한다. 

 

 

공통 레이아웃이 되는 Decorator 정의 (Layout.html)

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
	  xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
	<title>개별 값으로 대체</title>
	<script src="your-common-script.js"></script>
</head>
<body>
	<section layout:fragment="content">
		<p>개별 구분에서 정의하는 내용</p>
	</section>
</body>
</html>

 

1. 타임리프 레이아웃 다이얼렉트를 이용하기 위해 XML 네임스페이스로 xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" 를 선언한다.

 

2. <title>은 fragment 템플릿에서 정의한 title 값으로 대체된다.

 

3. 공통으로 이용하는 CSS 파일이나 자바스크립트 파일 등의  리소스를 설정한다.

 

4. Fragment에서 정의하는 내용에 대체하고 싶은 요소에 layout:fragment 속성을 부여한다.

 

 

개별 부분이 되는 Fragment정의 (Part.html)

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
	  xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorator="Layout">
<head>
	<title>개별 제목</title>
	<script src="content-script.js"></script>
</head>
<body>
	<section layout:fragment="content">
		<p>개별 내용</p>
	</section>
</body>
</html>

1. 타임리프 레이아웃 다이얼렉트를 이용하기 위해 XML 네임스페이스로 xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" 를 선언한다. layout:decorator 속성에서 공통적인 템플릿으로 이용하는 Decorator 뷰 이름을 지정한다.

 

2. Decorator <title>을 대체하기 위한 Fragment 템플릿에서 <title>을 정의한다. 최종적으로 개별 제목이 된다.

 

3. 개별적으로 필요한 CSS 파일이나 자바스크립트 파일 등의 리소서를 설정한다. Fragment 템플릿의 <head> 요소에 기술한 요소는 Decorator 템플릿의 <head> 요소에 추가된다. 최종적으로 <script src="your-common-script.js"></script> <script src="content-script.js"></script> 의 두 가지가 Part.html에 저장된다.

 

4. Decorator에서 layout:frgment 속성을 부여한 요소를 대체되기 때문에 그 내용이 되는 요소에 layout:fragment 속성을 부여한다. 타임리프에서 처리한 결과, Fragment인 Part.html의 <section layout:fragment="content">의 내용이 HTML에 설정된다.