개념
template의 사전적 의미는 견본, 형판이다.
의미를 HTML에 적용하면 특정 영역을 견본처럼 때어낸 독립적인 형태를 말하며, 이런 형태는 견본처럼 여기저기서 사용할 수 있게 한다.
너무 거창하게 설명하는 것 같다....... 아래 그림을 보자.
Page1과 Page2에서 공통으로 사용하는 Header영역을 템플릿 조각이다.
이렇게 템플릿 조각을 사용하면 중복되는 코드를 막을 수 있고 Header에 수정사항이 발생해도 공통으로 사용하기 때문에 Page1과 Page2도 동일하게 수정사항이 반영된다.
이제 예제를 보면서 사용방법을 알아보자!
예제
디렉토리 구조
Controller
@Controller
@RequestMapping("/main")
public class MainController {
@GetMapping("")
public String main() {
return "main";
}
}
/main으로 요청 시 main.html을 응답하는 단순한 controller다.
header.html
<!DOCTYPE html>
<html lang="ko" xmlns="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1 th:fragment="header">Header</h1>
</body>
</html>
👉 <h1 th:fragment="header">Header</h1>
- th:fragment=”템플릿 조각 이름”
- th:fragment는 템플릿 조각을 선언하고 조각의 네이밍을 붙인다.
- 예제에서 header 템플릿 조각을 만든 것 이다.
- 해당 조각은 main.html에서 사용된다.
main.html
<!DOCTYPE html>
<html lang="ko" xmlns="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div th:insert="~{layouts/header :: header}"></div>
<div th:replace="~{layouts/header :: header}"></div>
<h1>Main Page</h1>
</body>
</html>
th:insert와 th:replace는 th:fragment 조각을 main.html에 import하는 역할을 한다.
결과적으로 import라는 동일한 기능을 가지고 있지만 약간의 차이가 있다.
차이는 아래 이미지에서 확인하자.
👉 <div th:insert="~{layouts/header :: header}"></div>
👉 <div th:replace="~{layouts/header :: header}"></div>
- insert와 replace 사용문법은 동일하다.
- ~{경로 :: 템플릿조각 이름}와 같이 사용하면 된다.
- 템플리조각 이름은 header.html에 th:fragment=”header”의 header를 의미한다.
- 경로 작성에 주의해야되는데, Thymeleaf에 특정한 설정이 없다면 기본 default 최상위 경로는 templates/ 로 시작한다.
th:insert는 th:insert가 작성된 태그 내부에 import하는 템플릿 조각을 추가한다.
반면에 th:replace는 th:replace가 작성된 태그를 삭제하고 템플릿 조각으로 대체 한다.
템플릿 조각에 데이터 넘기기
main.html
<!DOCTYPE html>
<html lang="ko" xmlns="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div th:insert="~{layouts/header :: header('데이터1', '데이터2')}"></div>
<h1>Main Page</h1>
</body>
</html>
👉 <div th:insert="~{layouts/header :: header('데이터1', '데이터2')}"></div>
- header템플릿 조각에 특정 데이터를 넘기고 싶다면 위 코드와 같이 파라미터로 넘기면 된다.
- 마치 함수와 비슷하다.
header.html
<!DOCTYPE html>
<html lang="ko" xmlns="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1 th:fragment="header(param1, param2)">
<p th:text="${param1}"></p>
<p th:text="${param2}"></p>
</h1>
<span th:text="${param1}"></span>
</body>
</html>
👉 <h1 th:fragment="header(param1, param2)"> .. </h1>
- main.html에서 넘어온 값은 위 코드와 같이 받으면 된다.
👉 <span th:text="${param1}"></span>
- 당연 위 코드 th:fragment범위를 벗어나기 때문에 출력 되지 않는다.
단순 문자 데이터가 넘어간다는건 controller에서 넘어온 데이터도 넘어 가지 않을까?!는 생각을 했다. (”당연하겠지!”라고 생각 했지만 한번 해보고 싶었다.)
controller에서 main.html로 객체를 넘기고 main.html에서 header.html에 객체를 넘겨보자.
Obj.class
public class Obj {
private String name;
private int age;
public Obj(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
값을 담기 위한 특별할게 없는 단순한 객체다. controller에서 해당 객체를 생성하고 데이터를 담아 main.html에 넘길 것 이다.
controller
@Controller
@RequestMapping("/main")
public class MainController {
@GetMapping("")
public String main(Model model) {
model.addAttribute("obj", new Obj("superpil", 10));
return "main";
}
}
Obj객체를 생성하고 객체를 main.html로 넘겨보자.
main.html와 header.html
<!DOCTYPE html>
<html lang="ko" xmlns="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div th:insert="~{layouts/header :: header(${obj})}"></div>
<h1>Main Page</h1>
</body>
</html>
<!DOCTYPE html>
<html lang="ko" xmlns="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1 th:fragment="header(obj)">
<p th:text="${obj.name}"></p>
<p th:text="${obj.age}"></p>
</h1>
</body>
</html>
👉 <div th:insert="~{layouts/header :: header(${obj})}"></div>
- ${obj}로 header.html에 객체를 넘길 수 있다.
👉 <h1 th:fragment="header(obj)"> ... </h1>
- 동일하게 값을 받아서 th:fragment범위 내에서 사용할 수 있다.
이렇게 오늘 공부한 th:fragment, th:insert, th:replace 예제는 모두 살펴봤다.
잘못된 내용이나 보충이 필요한 내용이 있다면 댓글 남겨 주세요!
주니어 개발자에게 큰 도움이 됩니다! 감사합니다! 😊
개발 기록
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!