View Template Engine
- Controller가 전달해준 데이터를 기반으로 동적인 html 문서를 생성해 주는 엔진
- 조건문, 반복문 등으로 문서를 완성한다.
- 기존 jsp는 View라고 하기에는 너무 많은 기능을 사용할 수 있어서 스프링에서 스펙 아웃 되었다.
- Spring framework은 Thymeleaf를 기본 제공한다.
프로젝트에 추가
- build.gradle 에 추가 후 Gradle refresh
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
Thymeleaf의 기본
- 확장자는 html
- html 태그에 다음과 같이 namespace를 추가하여 사용한다.
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
- 일반 html과 동일하게 동작하지만 th: 로 표기된 항목만 동적으로 구성한다.
<p th:text=“${username}">User</p>
- 서버를 켜기 전에 html을 확인하면 User가 출력되고 서버가 켜지면 Controller에서 넘겨준 값이 출력된다.
- html 문법이 익숙하고, 서버 구현 전에 CSS 등을 미리 확인할 수 있는 장점이 있다.
- ${value}
- Controller 에서 model.addAttribute(”value”, xx) 로 넘겨준 값
- ${params.value}
- Request parameter의 값
- ${session.value}
- ${application.value}
프로젝트 예제
- Entity에 추가
@NoArgsConstructor // 생성자에서 하나도 없이 생성할 수 있다.
@Builder
@AllArgsConstructor // 값이 다 있어도 생성자를 생성할 수 있다.
- com.example.myschool.web 패키지 추가하고 WebController 추가
package com.example.myschool.web;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.example.myschool.teacher.domain.Teacher;
@Controller
public class WebController {
@GetMapping("/")
public String index(Model model) {
Teacher teacher = Teacher.builder().teacherId(1).name("JavaKim").description("No.1 Java Teacher").build();
model.addAttribute("username", "hello");
model.addAttribute("teacher", teacher);
return "index";
}
}
- resources/tempate/index.html 작성
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<p th:text="abc"></p>
<p th:text="1+1"></p> <!-- 계산 결과 출 -->
<div th:if="${username} != null">
<p th:text="${username}+'님 반갑습니다'"></p> <!-- String + String -->
<p th:text="|${username}님 반갑습니다.|"></p><!-- 변수부분과 일반 텍스트가 merge가 되어 한줄로 return 됨 -->
</div>
<div th:if="${teacher} != null" th:object="${teacher}"> <!-- th:object 는 이 div안에서 바로 호출하여 사용할 수 있다. -->
<h2 th:text="${teacher.name}"></h2> <!-- 만약 <div> 밖이라면 이런식으로 부름 -->
<p th:text="*{description}"></p> <!-- 속성을 즉시 불러서 사용할 수 있음. -->
</div>
</body>
</html>
- 태그에 th:object 로 선언된 경우 자식 요소에서 다음과 같이 축약하여 사용할 수 있다.
- *{propertyName}
<div th:if="${teacher} != null" th:object="${teacher}"> <!-- th:object 는 이 div안에서 바로 호출하여 사용할 수 있다. --> <h2 th:text="${teacher.name}"></h2> <!-- 만약 <div> 밖이라면 이런식으로 부름 --> <p th:text="*{description}"></p> <!-- 속성을 즉시 불러서 사용할 수 있음. --> </div>
- 링크 만들기 + 동적인 요소를 포함하는 동적인 링크 만들기
- Query String :
<a th:href=”@{/teachers(name=${teacher.name}, orderBy=’teacherId’)}”>TEST</a>
- Path Variable :
<a th:href=”@{/teachers/{id}(id=${teacher.teacherId})}”>TEST</a>
- Query String :
- if문
- th:if= - if
- th:unless= - else
- switch문
- th:switch=
- th:case=
레이아웃 관리하기
- 웹 페이지의 디자인을 구성하기 위해 다음 두 가지 방법 중 하나를 사용할 수 있다.
- UI 조각인 Fragment를 만든 다음 각 파일에서 include 하는 방법
- 파일 단위로 include 하지 않고 fragement 단위로 불러올 수 있다.
- fragment.html 파일 작성
<div th:fragment="header">
<h1>Header</h1>
</div>
<div th:fragment="footer">
<h1>Footer</h1>
</div>
- Fragment 불러 사용하기
- index.html에서 불러 쓰기
<div th:replace="~{fragment::header}"></div>
<div th:insert="~{fragment::footer}"></div>
~{파일 이름 :: fragment 이름}
- th:replace → 지금 태그를 fragment로 대체
- th:insert → 지금 태그의 자식 태그로 fragment를 추가
- Fragment를 부를 때 파라미터를 전달할 수 있다.
- fragment.html 수정
<head th:fragment="head(title)"> <meta charset="UTF-8"> <title th:text="${title}"></title> <!-- CSS --> <!-- JS --> </head>
- → 공통된 head 부분을 사용하는데 title은 페이지가 이동할 때마다 바뀌고 싶다..
- 불러오는 쪽.html 수정
<div th:replace="~{fragment::header('HOME')}"></div>
- head.html
<head th:fragment="head(title)">
<meta charset="UTF-8">
<title th:replace="${title}">TITLE</title>
<!-- CSS -->
<link rel="stylesheet" type="text/css" href="/main.css">
<!-- JS -->
</head>
- index.html
<head th:replace="~{head::head(~{::title})}">
<title>asfasdfs</title>
</head>
- title 태그를 파라미터로 넘겨서 head.html에 있는
→ 모든페이지에서 공용으로 사용하는 CSS나 JS가 있고, 어떠한 페이지에 추가 되는 스크립트나 CSS 등을 추가해줄 때 파라미터로 넘겨줘서 사용할 수 있다.
레이아웃 작업하기
- 파라미터로 page title, 페이지 전용 css, js, 그리고 contents 부분을 전달받는 layout.html을 작성한다.
- 각 페이지는 title, css, js, contents 부분을 파라미터로 넘기고 내 html을 layout으로 replace한다.
- layout.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" th:fragment="layout(title, link, content)">
<head>
<meta charset="UTF-8">
<title th:replace="${title}">title</title>
<th:block th:replace="${link}"></th:block> <!-- -->
<link rel="stylesheet" type="text/css" href="/main.css" id="css">
</head>
<body>
<!-- 공통 메뉴 부분 -->
<a th:href="@{/}">Home</a>
<a th:href="@{/view-teachers}">Teachers</a>
<a th:href="@{/view-lectures}">Lectures</a>
<br>
<div th:replace="${content}"></div> <!-- 들어올 컨텐츠 부분 -->
</body>
</html>
- index.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" th:replace="~{layout::layout(~{::title}, ~{::link}, ~{::#content})}"> <head> <title>Home</title> <link rel="stylesheet" type="text/css" href="/index.css"> </head> <body> <div id="content"> <h1>My_school HOME</h1> </div> </div> </body> </html>
패키지 전체 View
https://github1s.com/ejeonghun/Springboot_docs/tree/main/Thymeleaf/MySchool/src/main
GitHub1s
github1s.com
Thymeleaf 문법
- ${ } : 변수
- *{ } : 특정 객체의 property. th:object와 함께 사용
- @{ } : 주소, 링크
- ~{ } : 태그
- | .. | : 리터럴 대체
View Template Engine
- Controller가 전달해준 데이터를 기반으로 동적인 html 문서를 생성해 주는 엔진
- 조건문, 반복문 등으로 문서를 완성한다.
- 기존 jsp는 View라고 하기에는 너무 많은 기능을 사용할 수 있어서 스프링에서 스펙 아웃 되었다.
- Spring framework은 Thymeleaf를 기본 제공한다.
프로젝트에 추가
- build.gradle 에 추가 후 Gradle refresh
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
Thymeleaf의 기본
- 확장자는 html
- html 태그에 다음과 같이 namespace를 추가하여 사용한다.
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
- 일반 html과 동일하게 동작하지만 th: 로 표기된 항목만 동적으로 구성한다.
<p th:text=“${username}">User</p>
- 서버를 켜기 전에 html을 확인하면 User가 출력되고 서버가 켜지면 Controller에서 넘겨준 값이 출력된다.
- html 문법이 익숙하고, 서버 구현 전에 CSS 등을 미리 확인할 수 있는 장점이 있다.
- ${value}
- Controller 에서 model.addAttribute(”value”, xx) 로 넘겨준 값
- ${params.value}
- Request parameter의 값
- ${session.value}
- ${application.value}
프로젝트 예제
- Entity에 추가
@NoArgsConstructor // 생성자에서 하나도 없이 생성할 수 있다.
@Builder
@AllArgsConstructor // 값이 다 있어도 생성자를 생성할 수 있다.
- com.example.myschool.web 패키지 추가하고 WebController 추가
package com.example.myschool.web;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.example.myschool.teacher.domain.Teacher;
@Controller
public class WebController {
@GetMapping("/")
public String index(Model model) {
Teacher teacher = Teacher.builder().teacherId(1).name("JavaKim").description("No.1 Java Teacher").build();
model.addAttribute("username", "hello");
model.addAttribute("teacher", teacher);
return "index";
}
}
- resources/tempate/index.html 작성
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<p th:text="abc"></p>
<p th:text="1+1"></p> <!-- 계산 결과 출 -->
<div th:if="${username} != null">
<p th:text="${username}+'님 반갑습니다'"></p> <!-- String + String -->
<p th:text="|${username}님 반갑습니다.|"></p><!-- 변수부분과 일반 텍스트가 merge가 되어 한줄로 return 됨 -->
</div>
<div th:if="${teacher} != null" th:object="${teacher}"> <!-- th:object 는 이 div안에서 바로 호출하여 사용할 수 있다. -->
<h2 th:text="${teacher.name}"></h2> <!-- 만약 <div> 밖이라면 이런식으로 부름 -->
<p th:text="*{description}"></p> <!-- 속성을 즉시 불러서 사용할 수 있음. -->
</div>
</body>
</html>
- 태그에 th:object 로 선언된 경우 자식 요소에서 다음과 같이 축약하여 사용할 수 있다.
- *{propertyName}
<div th:if="${teacher} != null" th:object="${teacher}"> <!-- th:object 는 이 div안에서 바로 호출하여 사용할 수 있다. --> <h2 th:text="${teacher.name}"></h2> <!-- 만약 <div> 밖이라면 이런식으로 부름 --> <p th:text="*{description}"></p> <!-- 속성을 즉시 불러서 사용할 수 있음. --> </div>
- 링크 만들기 + 동적인 요소를 포함하는 동적인 링크 만들기
- Query String :
<a th:href=”@{/teachers(name=${teacher.name}, orderBy=’teacherId’)}”>TEST</a>
- Path Variable :
<a th:href=”@{/teachers/{id}(id=${teacher.teacherId})}”>TEST</a>
- Query String :
- if문
- th:if= - if
- th:unless= - else
- switch문
- th:switch=
- th:case=
레이아웃 관리하기
- 웹 페이지의 디자인을 구성하기 위해 다음 두 가지 방법 중 하나를 사용할 수 있다.
- UI 조각인 Fragment를 만든 다음 각 파일에서 include 하는 방법
- 파일 단위로 include 하지 않고 fragement 단위로 불러올 수 있다.
- fragment.html 파일 작성
<div th:fragment="header">
<h1>Header</h1>
</div>
<div th:fragment="footer">
<h1>Footer</h1>
</div>
- Fragment 불러 사용하기
- index.html에서 불러 쓰기
<div th:replace="~{fragment::header}"></div>
<div th:insert="~{fragment::footer}"></div>
~{파일 이름 :: fragment 이름}
- th:replace → 지금 태그를 fragment로 대체
- th:insert → 지금 태그의 자식 태그로 fragment를 추가
- Fragment를 부를 때 파라미터를 전달할 수 있다.
- fragment.html 수정
<head th:fragment="head(title)"> <meta charset="UTF-8"> <title th:text="${title}"></title> <!-- CSS --> <!-- JS --> </head>
- → 공통된 head 부분을 사용하는데 title은 페이지가 이동할 때마다 바뀌고 싶다..
- 불러오는 쪽.html 수정
<div th:replace="~{fragment::header('HOME')}"></div>
- head.html
<head th:fragment="head(title)">
<meta charset="UTF-8">
<title th:replace="${title}">TITLE</title>
<!-- CSS -->
<link rel="stylesheet" type="text/css" href="/main.css">
<!-- JS -->
</head>
- index.html
<head th:replace="~{head::head(~{::title})}">
<title>asfasdfs</title>
</head>
- title 태그를 파라미터로 넘겨서 head.html에 있는
→ 모든페이지에서 공용으로 사용하는 CSS나 JS가 있고, 어떠한 페이지에 추가 되는 스크립트나 CSS 등을 추가해줄 때 파라미터로 넘겨줘서 사용할 수 있다.
레이아웃 작업하기
- 파라미터로 page title, 페이지 전용 css, js, 그리고 contents 부분을 전달받는 layout.html을 작성한다.
- 각 페이지는 title, css, js, contents 부분을 파라미터로 넘기고 내 html을 layout으로 replace한다.
- layout.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" th:fragment="layout(title, link, content)">
<head>
<meta charset="UTF-8">
<title th:replace="${title}">title</title>
<th:block th:replace="${link}"></th:block> <!-- -->
<link rel="stylesheet" type="text/css" href="/main.css" id="css">
</head>
<body>
<!-- 공통 메뉴 부분 -->
<a th:href="@{/}">Home</a>
<a th:href="@{/view-teachers}">Teachers</a>
<a th:href="@{/view-lectures}">Lectures</a>
<br>
<div th:replace="${content}"></div> <!-- 들어올 컨텐츠 부분 -->
</body>
</html>
- index.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" th:replace="~{layout::layout(~{::title}, ~{::link}, ~{::#content})}"> <head> <title>Home</title> <link rel="stylesheet" type="text/css" href="/index.css"> </head> <body> <div id="content"> <h1>My_school HOME</h1> </div> </div> </body> </html>
패키지 전체 View
https://github1s.com/ejeonghun/Springboot_docs/tree/main/Thymeleaf/MySchool/src/main
GitHub1s
github1s.com
Thymeleaf 문법
- ${ } : 변수
- *{ } : 특정 객체의 property. th:object와 함께 사용
- @{ } : 주소, 링크
- ~{ } : 태그
- | .. | : 리터럴 대체