반복적으로 사용되는 템플릿을 공통사항으로 만들어 재사용하는 방법이 있다. 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에 설정된다.
'이론 > Spring' 카테고리의 다른 글
[Spring] 컴포넌트 스캔과 의존관계 자동 주입 시작하기 (0) | 2021.08.01 |
---|---|
[Spring] @Configuration과 바이트코드 조작 (0) | 2021.07.26 |
[Spring] BeanFactory와 ApplicationContext / 스프링 컨테이너 (0) | 2021.07.25 |
[Spring] 스프링 컨테이너에 등록된 빈 조회 / Bean 조회 / 출력 (0) | 2021.07.24 |
[Spring Boot 템플릿 엔진] 타임리프(Thymeleaf) / 표현식 / 출력제어 (0) | 2021.07.09 |