일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 고전역학
- 자바네트워크
- GPT-4's answer
- Java
- 코틀린
- spring data jpa
- 데이터베이스
- 리눅스
- Database
- 역학
- 소프트웨어공학
- kotlin
- jpa
- 웹 크롤링
- 인프라
- spring integration
- 시스템
- 자바
- NIO
- write by GPT-4
- JVM
- 자바암호
- flet
- oracle
- write by chatGPT
- android
- 유닉스
- 파이썬
- chatGPT's answer
- python
- Today
- Total
Akashic Records
타임리프(Thymeleaf) 본문
타임리프(Thymeleaf)는 자바 기반의 서버 사이드 템플릿 엔진으로, 주로 스프링 프레임워크(Spring Framework)와 함께 사용됩니다. HTML, XML, JavaScript, CSS 등을 자연스럽게 처리할 수 있는 기능을 제공하여, 뷰 템플릿을 손쉽게 생성하고 데이터와 결합할 수 있도록 도와줍니다.
타임리프는 특히 스프링 MVC와 통합이 잘 되어 있어, 서버에서 제공되는 데이터를 HTML 기반의 동적인 웹 페이지로 쉽게 표현할 수 있습니다. 기본적으로 타임리프는 HTML을 템플릿으로 사용하면서도 웹 브라우저에서 바로 볼 수 있는 형태로 디자인되어 있어, 프론트엔드 개발자와 협업이 매우 용이하다는 장점이 있습니다.
타임리프의 주요 특징과 기능들을 살펴보면 다음과 같습니다:
1. 자연 템플릿(Natural Templates)
- 타임리프는 HTML 파일을 "그대로" 템플릿으로 사용하여, 서버 측 템플릿 엔진을 사용하기 전에도 브라우저에서 볼 수 있습니다. 즉, 타임리프 태그가 있어도 유효한 HTML 문서로 동작합니다.
- 예를 들어, 개발 중 브라우저에서 템플릿 파일을 열어 볼 수 있고, 이 파일을 그대로 사용하여 백엔드와 통합할 수 있습니다.
2. 스프링과의 긴밀한 통합
- 타임리프는 스프링 MVC와 밀접하게 통합되어 있으며, 모델 속성을 손쉽게 렌더링할 수 있습니다. 이를 통해 컨트롤러에서 제공하는 데이터를 템플릿에 쉽게 전달하고, 이를 표현할 수 있습니다.
- 스프링의 기본적인 설정에 타임리프 뷰 리졸버(View Resolver)를 추가하여, JSP 대신 타임리프 템플릿을 사용할 수 있습니다.
3. 표현식 언어(Thymeleaf Expression Language)
- 타임리프는 다양한 표현식 언어를 사용하여 HTML 템플릿 내에 서버에서 제공되는 데이터를 출력합니다.
- 표현식 유형:
${}
변수 표현식: 모델 속성에 접근합니다.#
Utility Object: 기본적인 유틸리티 기능 제공 (#dates
,#numbers
등).@{}
URL 표현식: URL을 생성합니다.~{}
프래그먼트 표현식: HTML 내 특정 프래그먼트를 참조합니다.
4. 조건부 렌더링과 반복
- 조건부 렌더링: 타임리프의
th:if
와th:unless
속성을 사용하여 특정 조건에 따라 HTML 요소를 렌더링할 수 있습니다.
<div th:if="${user != null}">
환영합니다, <span th:text="${user.name}">사용자 이름</span>!
</div>
- 반복 처리: th:each 속성을 사용하여 컬렉션을 순회하며 반복적으로 HTML 요소를 생성할 수 있습니다.
<ul>
<li th:each="item : ${items}" th:text="${item.name}">아이템 이름</li>
</ul>
5. 프래그먼트와 레이아웃
- 타임리프는 프래그먼트(Fragments) 기능을 제공하여, 템플릿 파일의 특정 부분을 다른 템플릿에서 재사용할 수 있습니다. 이를 통해 코드의 중복을 줄이고 유지보수를 쉽게 할 수 있습니다.
<!-- header.html -->
<header th:fragment="site-header">
<h1>사이트 헤더</h1>
</header>
<!-- main.html -->
<div th:insert="fragments/header :: site-header"></div>
- 또한, 템플릿 파일들을 결합하여 페이지의 공통 레이아웃을 구성할 수 있습니다. 레이아웃을 사용하면 페이지의 일관성을 유지하면서 반복적인 요소를 쉽게 관리할 수 있습니다. 아래 예시에서 home.html은 기본 레이아웃 default.html을 사용하여 페이지의 일관된 구조를 유지하며, 콘텐츠 부분만 정의합니다.
레이아웃 템플릿 (layouts/default.html):
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title th:text="${pageTitle}">기본 페이지 제목</title>
<link rel="stylesheet" href="/css/style.css" />
</head>
<body>
<header layout:fragment="header">
<nav>
<ul>
<li><a href="/home">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
</header>
<main layout:fragment="content">
<!-- 기본 콘텐츠가 여기에 들어갑니다 -->
</main>
<footer layout:fragment="footer">
<p>Copyright © 2024 My Website</p>
</footer>
</body>
</html>
페이지별 콘텐츠 템플릿 (views/home.html):
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layouts/default}">
<head>
<title>홈페이지</title>
</head>
<body>
<div layout:fragment="content">
<h2>환영합니다!</h2>
<p>이곳은 홈페이지입니다. 최신 소식을 확인하세요.</p>
</div>
</body>
</html>
6. 국제화(i18n) 지원
- 타임리프는 국제화 메시지를 간단히 처리할 수 있습니다. 스프링의 메시지 번들 파일을 활용해 다국어 지원을 할 수 있습니다.
<p th:text="#{welcome.message}">Welcome message here</p>
7. HTML 속성 조작
- 타임리프는 HTML 요소의 속성을 동적으로 설정할 수 있는 기능을 제공합니다. 예를 들어
th:href
,th:src
,th:class
등을 사용하여 속성 값을 동적으로 변경할 수 있습니다.
<a th:href="@{/home}" th:text="'홈으로 이동'">링크</a>
타임리프 사용 예시
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Thymeleaf 예제</title>
</head>
<body>
<h1 th:text="'안녕하세요, ' + ${username} + '님!'">Hello, User!</h1>
<ul>
<li th:each="item : ${items}" th:text="${item}">아이템 이름</li>
</ul>
<form th:action="@{/submit}" method="post">
<input type="text" name="name" th:value="${user.name}"/>
<button type="submit">제출하기</button>
</form>
</body>
</html>
이 예시는 타임리프의 표현식과 속성 조작을 이용하여, 서버에서 전달된 데이터를 동적으로 HTML에 바인딩하는 방법을 보여줍니다.
타임리프와 JSP의 차이점
- HTML 친화성: 타임리프는 브라우저에서 유효한 HTML로 동작하기 때문에 디자이너와 협업하기 좋습니다. 반면, JSP는 브라우저에서 직접 열기에는 적합하지 않습니다.
- 확장성: 타임리프는 다양한 템플릿 파일을 조합하거나 레이아웃을 구성하는 데 유리한 기능들을 제공합니다.
- 성능: 타임리프는 템플릿 엔진으로서 성능이 우수하며, 특히 스프링 환경에서 사용될 때 더욱 최적화된 경험을 제공합니다.
타임리프 아키텍쳐
타임리프는 이렇게 스프링 MVC 애플리케이션의 뷰를 쉽고 효율적으로 개발할 수 있는 도구로서, 직관적인 문법과 강력한 기능을 통해 서버와 클라이언트 간의 데이터를 매끄럽게 연결하는 역할을 합니다.
타임리프(Thymeleaf)는 동적인 웹 페이지를 생성하기 위해 서버 사이드 템플릿 엔진으로 동작하며, 그 내부에는 웹 애플리케이션과의 상호작용을 효율적으로 처리하기 위한 구조적 아키텍처가 포함되어 있습니다. 이 아키텍처는 뷰 렌더링을 쉽게 하고 확장 가능하도록 설계되어 있어 스프링 MVC와 같은 프레임워크에서 널리 사용됩니다. 타임리프 아키텍처의 기본 개념을 이해하면, 그 작동 원리와 사용 방법을 더 잘 활용할 수 있습니다.
타임리프의 아키텍처는 크게 템플릿, 템플릿 프로세서, 표현식 언어, 컨텍스트 등의 개념으로 구성됩니다. 각 구성 요소가 어떤 역할을 하고, 어떻게 서로 연동되는지 살펴보겠습니다.
1. 템플릿(Template)
- 템플릿은 HTML, XML, JavaScript, 텍스트 파일 등과 같이, 렌더링될 기본적인 문서 구조입니다.
- 템플릿 파일은 일반적인 HTML로 구성되며, 여기에 타임리프 전용 속성(예:
th:text
,th:each
등)이 추가되어 서버 측 데이터가 동적으로 주입될 수 있도록 합니다. - 타임리프의 주요 목표는 이러한 템플릿을 자연스럽게 사용할 수 있도록 지원하는 것으로, 프론트엔드와 백엔드 모두에서 쉽게 사용할 수 있습니다.
2. 템플릿 엔진과 템플릿 프로세서(Template Engine & Template Processor)
- 타임리프 아키텍처의 핵심에는 템플릿 엔진이 존재합니다. 템플릿 엔진은 개발자가 작성한 템플릿 파일을 해석하고 렌더링하여 최종 HTML 문서를 생성합니다.
- 템플릿 엔진은 여러 종류의 템플릿 프로세서와 상호작용하며, 이 프로세서들은 각각의 특정 목적을 가진 플러그인 역할을 합니다. 예를 들어 HTML 프로세서, 텍스트 프로세서 등이 있습니다.
- 템플릿 프로세서는 문서의 각 요소를 처리하며, 예를 들어 HTML 프로세서는 HTML 태그 내의 타임리프 속성(
th:*
)을 해석하고 이를 데이터와 결합해 최종 결과를 만들어냅니다.
3. 컨텍스트(Context)
- 컨텍스트는 템플릿이 렌더링될 때 필요한 데이터가 저장되는 공간입니다. 쉽게 말해 템플릿을 렌더링할 때 사용하는 데이터 모델입니다.
- 이 컨텍스트 객체는 주로 서버의 컨트롤러에서 생성되며, 템플릿 엔진에 전달됩니다.
- 예를 들어, 스프링 MVC 컨트롤러에서 모델 데이터를
Model
이나ModelMap
에 저장하면 타임리프는 이를 템플릿의 컨텍스트로 활용하여 데이터에 접근할 수 있습니다.위의 코드에서model.addAttribute("name", "John")
은 템플릿에서${name}
으로 접근 가능한 데이터를 제공합니다.
@Controller
public class MyController {
@GetMapping("/hello")
public String hello(Model model) {
model.addAttribute("name", "John");
return "hello";
}
}
4. 표현식 언어(Expression Language)
- 타임리프 표현식 언어(Thymeleaf Expression Language)는 컨텍스트에 포함된 데이터에 접근하고 이를 변형하거나 출력을 결정하는 데 사용됩니다. 아래에서 자세히 설명
5. 템플릿 리졸버(Template Resolver)
- 템플릿 리졸버는 템플릿 파일의 위치를 지정하고 해당 파일을 찾는 역할을 합니다.
- 타임리프는 템플릿 리졸버를 통해 지정된 경로에서 템플릿 파일을 찾고, 이를 템플릿 엔진이 렌더링할 수 있도록 전달합니다.
- 스프링 부트와 통합 시, 기본적으로
resources/templates/
디렉터리에서 템플릿 파일을 찾도록 설정되어 있습니다.
6. 다이얼렉트(Dialect)
- 다이얼렉트는 타임리프에 다양한 템플릿 처리 기능을 추가하는 확장 모듈입니다. 기본적으로 타임리프는 표준 다이얼렉트(Standard Dialect)를 제공하며, 이는 HTML 템플릿에서 사용하는 대부분의 기능(
th:text
,th:if
,th:each
등)을 포함하고 있습니다. - 개발자는 필요에 따라 커스텀 다이얼렉트(Custom Dialect)를 정의하여, 추가적인 기능을 타임리프에 통합할 수 있습니다. 이를 통해 복잡한 비즈니스 로직을 손쉽게 처리할 수 있습니다.
8. 렌더링 흐름(Rendering Flow)
- 타임리프 아키텍처의 주요 흐름은 다음과 같습니다:
- 컨트롤러가 요청을 처리하고, 데이터와 함께 특정 템플릿 파일을 반환합니다.
- 템플릿 리졸버가 지정된 위치에서 해당 템플릿 파일을 찾습니다.
- 템플릿 엔진이 컨텍스트와 템플릿을 받아 최종적인 HTML을 생성합니다.
- 최종적으로 생성된 HTML은 서버에서 클라이언트(브라우저)로 반환됩니다.
타임리프 문법
타임리프(Thymeleaf)는 HTML 기반 템플릿을 서버 측 데이터와 결합하기 위해 다양한 표현식과 문법을 제공합니다. 이러한 표현식은 동적으로 HTML 문서 내의 데이터를 삽입하거나, 조건부 로직을 적용하거나, 반복문을 사용하여 데이터를 표현하는 데 사용됩니다. 아래에서는 타임리프에서 자주 사용하는 표현식과 문법을 자세히 살펴보겠습니다.
1. 변수 표현식 (Variable Expressions) - ${}
변수 표현식은 모델에 포함된 데이터에 접근하는 데 사용됩니다. 스프링 컨트롤러에서 전달된 모델 데이터는 ${}
구문을 통해 템플릿에서 접근할 수 있습니다.
<p th:text="${user.name}">사용자 이름</p>
- 위의 예시에서
${user.name}
은 모델 속성user
의name
필드를 참조하여 출력합니다.
2. 선택 변수 표현식 (Selection Variable Expressions) - *{}
선택 변수 표현식은 특정 객체를 기준으로 데이터를 접근할 때 사용됩니다. 주로 th:object
와 함께 사용되며, 폼에서 데이터를 다룰 때 유용합니다.
<form th:object="${user}">
<input type="text" th:field="*{name}" />
</form>
- 여기서
*{name}
은user
객체의name
필드를 참조합니다.th:object
로 지정된 객체가 기준이 되기 때문에 더 간단하게 사용 가능합니다.
3. 메시지 표현식 (Message Expressions) - #{}
메시지 표현식은 국제화(i18n) 메시지를 처리하는 데 사용됩니다. 스프링의 메시지 번들에서 정의된 값을 가져옵니다.
<p th:text="#{welcome.message}">Welcome message here</p>
- 여기서
#{welcome.message}
는 메시지 번들 파일에 정의된welcome.message
키의 값을 출력합니다. 다국어 지원을 위해 매우 유용합니다.
4. 링크 URL 표현식 (Link URL Expressions) - @{}
URL 표현식은 동적인 URL을 생성할 때 사용됩니다. 컨텍스트 경로를 자동으로 포함하거나 경로 변수 및 쿼리 파라미터를 처리할 수 있습니다.
<a th:href="@{/home}">홈으로 이동</a>
<a th:href="@{/user/profile(id=${user.id})}">프로필 보기</a>
@{/user/profile(id=${user.id})}
는user.id
값을 경로 변수로 포함하여 URL을 생성합니다.
5. 프래그먼트 표현식 (Fragment Expressions) - ~{}
프래그먼트 표현식은 타임리프 템플릿 내의 특정 부분을 참조할 때 사용됩니다. 이를 통해 공통 컴포넌트를 쉽게 재사용할 수 있습니다.
<div th:insert="~{fragments/header :: site-header}"></div>
~{fragments/header :: site-header}
는fragments/header.html
파일에서site-header
라는 프래그먼트를 삽입합니다.
6. 조건부 표현식 - th:if
, th:unless
조건부 표현식을 사용하여 특정 HTML 요소의 렌더링 여부를 결정할 수 있습니다.
<p th:if="${user != null}">환영합니다, <span th:text="${user.name}">사용자 이름</span>님!</p>
<p th:unless="${user != null}">로그인 해주세요.</p>
th:if
는 주어진 조건이 참일 때만 해당 요소를 렌더링하며,th:unless
는 조건이 거짓일 때 렌더링합니다.
7. 반복 표현식 - th:each
컬렉션을 순회하며 HTML 요소를 반복해서 렌더링할 때 사용합니다.
<ul>
<li th:each="item : ${items}" th:text="${item.name}">아이템 이름</li>
</ul>
th:each="item : ${items}"
는items
컬렉션을 순회하며, 각 아이템에 대해<li>
요소를 생성합니다.
8. 텍스트 및 속성 변경 표현식
타임리프는 텍스트나 속성을 동적으로 설정하는 속성을 제공하여 HTML 태그 내부에 데이터를 바인딩할 수 있습니다.
- 텍스트 설정 (
th:text
): 태그의 텍스트 내용을 동적으로 설정합니다.${user.name}
의 값을 스팬 태그 내부에 출력합니다.
<span th:text="${user.name}">기본 텍스트</span>
- 속성 설정 (
th:href
,th:src
,th:class
등): HTML 속성에 동적 값을 설정합니다.
<a th:href="@{/home}" th:text="'홈으로 이동'">링크</a>
<img th:src="@{/images/logo.png}" alt="로고 이미지">
9. 기타 표현식
타임리프에는 여러 가지 표현식을 통해 다양한 동적 처리를 할 수 있습니다.
- 기본 객체 접근 (
#
): 타임리프는 여러 기본 객체에 대한 접근을 제공합니다. 예를 들어, 날짜 및 숫자 처리에 유용한 객체들이 있습니다.#dates
는 날짜 관련 유틸리티 객체입니다.<p th:text="${#dates.format(user.birthDate, 'yyyy-MM-dd')}">생일</p>
- 배열과 리스트 표현:
- 인덱스를 사용할 수 있습니다. 예:
itemStat.index
또는itemStat.count
<li th:each="item, itemStat : ${items}"> <span th:text="${item.name}">아이템 이름</span> <span th:text="${itemStat.index}">인덱스</span> </li>
- 인덱스를 사용할 수 있습니다. 예:
10. 기본 연산자와 조건부 논리
타임리프 표현식은 다양한 연산자를 지원하여 논리적 처리를 할 수 있습니다.
- 산술 연산자:
+
,-
,*
,/
,%
를 사용할 수 있습니다.<span th:text="${user.age + 1}">나이</span>
- 비교 연산자:
>
,<
,>=
,<=
,==
,!=
<p th:if="${user.age > 18}">성인입니다.</p>
- 논리 연산자:
and
,or
,!
<p th:if="${user.age > 18 and user.gender == 'M'}">성인 남성입니다.</p>
- 조건부 연산자 (삼항 연산자):
condition ? ifTrue : ifFalse
<p th:text="${user.age > 18 ? '성인' : '미성년자'}"></p>
'Spring for Beginners' 카테고리의 다른 글
Spring Security 는 처음이에요. (1) | 2024.02.27 |
---|---|
Spring Rest API는 처음인데요. (0) | 2024.02.22 |
Spring JPA는 처음인데요. (0) | 2024.02.19 |
@SpringBootApplication (1) | 2024.02.13 |
Spring Boot 첫 번째 예제 (0) | 2024.02.13 |