타임리프란?
타임리프(Thymeleaf)는 자바 웹 애플리케이션 개발에 사용되는 모던 서버사이드 Java 템플릿 엔진 중 하나이다.
HTML, XML, 텍스트, 자바스크립트, CSS 등 다양한 마크업 파일을 생성할 수 있으며, 주로 웹 애플리케이션에서 동적인 뷰를 생성하는 데 사용된다.
타임리프의 가장 큰 특징 중 하나는 natural templates 을 지원한다는 것으로, 애플리케이션이 실행되지 않는 상태에서도 HTML 파일을 웹 브라우저에서 직접 열어볼 수 있다.
이는 개발 과정을 보다 효율적으로 만들어준다.
타임리프의 주요 특징
네츄럴 템플릿: 타임리프 템플릿은 실행되지 않는 상태에서도 HTML 파일로서 자연스럽게 보여질 수 있어, 디자이너와 개발자 간의 협업을 용이하게 한다.
- 서버 사이드 렌더링(SSR) : 타임리프는 백엔드 서버에서 HTML을 동적으로 렌더링하는 용도로 사용된다.
- 스프링 프레임워크와의 통합: 스프링 MVC와 뛰어난 통합성을 제공하여, 스프링 애플리케이션에서 뷰 레이어를 구성하는 데 적합하다.
- 표준 기반: HTML5, XML 등의 웹 표준을 준수하며, 다양한 브라우저와 잘 호환된다.
- 국제화(i18n) 지원: 다국어 애플리케이션을 개발하는 데 필요한 국제화 기능을 지원한다.
- 풍부한 표현식: 변수 표현, 조건문, 반복문, URL 처리 등 다양한 표현식을 제공하여, 동적인 데이터 바인딩과 조작을 쉽게 할 수 있다.
사용법
타임리프 사용 선언
타임리프는 문서 최상단에 아래와 같은 코드를 넣어서 사용할 수 있다.
<html xmlns:th="http://www.thymeleaf.org">
타임리프 핵심
th:xxx가 붙은 부분은 서버사이드에서 렌더링 되고, 기존 것을 대체한다.
th:xxx이 없으면 기존 HTML의 xxx 속성이 그대로 사용된다.
HTML을 파일로 직접 열었을 때, th:xxx가 있어도 웹 브라우저는 th: 속성을 알지 못하므로 무시한다.
따라서 HTML 파일 보기를 유지하면서 템플릿 기능도 할 수 있다.
속성 변경
타임리프에서 속성 변경은 HTML 요소의 속성을 동적으로 변경하거나 추가하는 기능을 제공한다.
이를 통해 HTML 문서에 정적인 값을 직접 작성하는 대신, 서버에서 생성된 데이터를 기반으로 속성 값을 설정할 수 있다.
속성 변경은 주로 링크, 이미지 소스, 클래스, 스타일 등의 HTML 속성을 동적으로 조작할 때 사용된다.
링크(href) 속성 변경: th:href를 사용하여 a 태그의 href 속성을 변경한다.
<a th:href="@{/path/to/resource}">링크</a>
여기서 @{...}는 타임리프의 URL 표현식이며, 서블릿 컨텍스트 경로를 포함한 전체 URL을 생성한다.
th:href th:href="@{/css/bootstrap.min.css}"
href="value1"을 th:href="value2"의 값으로 변경한다.
타임리프 뷰 템플릿을 거치게 되면 원래 값을 th:xxx 값으로 변경한다.
만약 값이 없다면 새로 생성한다. HTML을 그대로 볼 때는 href 속성이 사용되고, 뷰 템플릿을 거치면 th:href의 값이 href로 대체되면서 동적으로 변경할 수 있다. 대부분의 HTML 속성을 th:xxx로 변경할 수 있다.
URL 링크 표현식 - @{...}
타임리프(Thymeleaf)의 URL 링크 표현식 @{...}은 웹 애플리케이션에서 동적으로 URL을 생성할 때 사용된다.
이 표현식을 사용하면 애플리케이션의 컨텍스트 경로를 자동으로 처리하고, URL 파라미터를 쉽게 추가할 수 있다.
URL 링크 표현식은 th:href, th:src, th:action 등 HTML 태그의 속성과 함께 사용되어, 리소스 링크, 이미지 소스, 폼 액션 등을 동적으로 설정한다.
상대 경로: @{/path/to/resource} 형식을 사용하여 애플리케이션의 루트 경로에 상대적인 URL을 생성한다.
<a th:href="@{/login}">로그인 페이지</a>
경로 변수: {variableName}를 사용하여 URL 경로에 변수를 포함시킨다. 경로 변수는 URL 표현식 내에서 괄호를 사용하여 전달한다.
<a th:href="@{/user/{id}(id=${user.id})}">사용자 아이디</a>
쿼리 파라미터: URL 뒤에 쿼리 파라미터를 추가하려면, 경로 변수와 유사한 방식으로 괄호 내에 쿼리 파라미터를 정의한다.
<a th:href="@{/search(name=${query})}">검색</a>
리터럴 대체: |...|를 사용하여 URL 표현식 내에서 직접 문자열을 결합할 수 있다. 이는 복잡한 URL을 생성할 때 유용하다.
<a th:href="@{|/user/${user.id}/profile|}">프로필</a>
리터럴 대체 - |...|
리터럴 대체는 타임리프(Thymeleaf)에서 문자열과 표현식을 편리하게 결합할 수 있는 기능이다.
기본적으로 타임리프 표현식 내에서 문자열과 변수를 결합하기 위해서는 + 연산자를 사용해야 한다.
하지만, 리터럴 대체를 사용하면 이러한 결합을 더욱 간결하게 표현할 수 있다. 리터럴 대체는 |...| 기호를 사용하여 표현된다.
다음과 같이 리터럴 대체 문법을 사용하면, 더하기 없이 편리하게 사용할 수 있다.
<span th:text="|Welcome to our application, ${user.name}!|">
리터럴 대체는 단순한 문자열 결합 뿐만 아니라, URL 생성과 같은 복잡한 문자열 표현에도 사용될 수 있다.
예를 들어, 다음과 같이 리터럴 대체를 사용하여 동적인 URL을 생성할 수 있다
<a th:href="@{|/user/${user.id}/profile|}">프로필 보기</a>
변수 표현식 - ${...}
타임리프(Thymeleaf)에서 변수 표현식은 데이터를 HTML 템플릿에 동적으로 삽입하기 위해 사용된다.
이 표현식은 모델에서 전달된 데이터나 세션, 요청 파라미터 등의 여러 소스에서 가져온 값을 HTML 문서 내에 표시할 때 활용된다.
변수 표현식은 ${...} 구문을 사용하여 정의된다.
변수 표현식을 사용하여 템플릿에 데이터를 삽입하는 기본 형태는 다음과 같다.
<p th:text="${message}">기본 메시지입니다.</p>
위 예제에서 th:text 속성을 사용하여 <p> 태그의 내용을 message 변수의 값으로 대체한다. 만약 message 변수가 모델에 존재하지 않으면, "기본 메시지입니다."라는 기본 텍스트가 표시된다.
객체의 프로퍼티 접근: 객체의 프로퍼티나 필드에 접근할 때는 점(.) 연산자를 사용한다.
<p th:text="${user.name}">사용자 이름</p>
리스트나 맵에서의 값 접근: 리스트의 특정 요소에 접근하거나 맵의 키에 해당하는 값을 가져올 때도 변수 표현식을 사용한다.
<p th:text="${users[0].name}">첫 번째 사용자의 이름</p>
<p th:text="${userMap['userKey'].name}">사용자 이름</p>
메소드 호출: 객체의 메소드를 호출하여 반환값을 활용할 수 있다.
<p th:text="${user.getFullName()}">사용자 전체 이름</p>
쿼리 파라미터 조회: 예를 들어, 클라이언트가 URL을 통해 http://example.com?status=active와 같은 요청을 보냈을 때, status 파라미터의 값을 타임리프 템플릿에서 다음과 같이 사용할 수 있다
<p>Status: <span th:text="${param.status}"></span></p>
반복 출력 - th:each
반복 출력은 th:each 속성을 사용하여 구현된다.
이 기능은 컬렉션의 각 항목에 대해 HTML 요소를 반복하여 렌더링하고자 할 때 사용된다. th:each는 배열, 리스트, 맵, 세트 등 자바의 모든 반복 가능한 컬렉션 타입에 사용할 수 있다.
th:each를 사용하여 반복 출력을 구현하는 기본 형태는 다음과 같다.
<ul>
<li th:each="item : ${items}" th:text="${item}"></li>
</ul>
이 예제에서 ${items}는 컬렉션 객체를 참조하는 변수이며, item은 반복 중인 현재 항목의 임시 변수 이름이다. th:each 속성이 적용된 HTML 요소(<li>)는 컬렉션의 각 항목에 대해 반복되어 렌더링된다.
맵(Map) 객체를 반복할 때는 키(key)와 값(value)을 모두 사용할 수 있다.
<div th:each="entry : ${map}">
<p>Key: <span th:text="${entry.key}"></span>, Value: <span th:text="${entry.value}"></span></p>
</div>
반복문에서 현재 항목의 인덱스를 사용하고 싶을 때는 반복 변수명 뒤에 index 또는 count를 추가한다. index는 0부터 시작하고, count는 1부터 시작한다.
<ul>
<li th:each="item, iterStat : ${items}" th:text="|${iterStat.index} - ${item}|"></li>
</ul>
이 예제에서 iterStat는 반복 상태를 나타내는 객체로, 현재 인덱스(iterStat.index), 카운트(iterStat.count), 그리고 반복 중인 컬렉션의 사이즈(iterStat.size) 등 다양한 정보를 제공한다.
th:if와 같은 조건 속성과 함께 th:each를 사용하여 특정 조건을 만족하는 항목에 대해서만 요소를 렌더링할 수 있다.
<ul>
<li th:each="item : ${items}" th:if="${item.active}" th:text="${item.name}"></li>
</ul>
이 예제에서는 item.active가 true인 항목에 대해서만 <li> 요소가 렌더링된다.
내용 변경 - th:text
th:text는 타임리프(Thymeleaf) 템플릿 엔진에서 HTML 요소의 텍스트 내용을 동적으로 설정하는 데 사용되는 속성이다.
이 속성을 사용하면 서버 사이드에서 생성된 데이터나 표현식의 결과를 웹 페이지의 특정 부분에 삽입할 수 있다
th:text를 사용함으로써 HTML 태그 내에 하드코딩된 텍스트 대신에, 애플리케이션의 모델이나 서비스 레이어에서 제공하는 동적인 데이터를 표시할 수 있다.
<td th:text="${item.price}">10000</td>
내용의 값을 th:text의 값으로 변경한다. 여기서는 10000을 ${item.price}의 값으로 변경한다.
th:text는 조건부 로직과 함께 사용될 수도 있다. 예를 들어, 사용자의 로그인 상태에 따라 다른 메시지를 표시하고 싶다면, 다음과 같이 작성할 수 있다.
<span th:text="${session.user != null} ? '로그인 상태입니다.' : '로그아웃 상태입니다.'">기본 텍스트</span>
조건식
th:if, th:unless
- th:if는 조건이 참일 경우에만 요소가 렌더링된다.
- th:unless는 조건이 거짓일 경우에만 요소가 렌더링된다.
<div th:if="${user != null}">
사용자 이름은 <span th:text="${user.name}">사용자명</span>
</div>
<div th:unless="${user != null}">
사용자 정보가 없습니다.
</div>
th:switch, th:case
- th:switch는 여러 조건 중 하나를 선택해 렌더링할 때 사용된다.
- th:case는 th:switch 내에서 각 조건을 정의한다.
<div th:switch="${user.role}">
<p th:case="'admin'">관리자</p>
<p th:case="'user'">일반 사용자</p>
<p th:case="*">알 수 없는 역할</p>
</div>
인라인 조건식
인라인에서의 조건식 사용은 [(${condition}) ? '값1' : '값2'] 형태로, 인라인에서 직접 조건식을 사용할 수 있다는 것이다.
<p>상태: <span th:inline="text">[(${user.active}) ? '활성' : '비활성']</span></p>
'Front-End > Thymeleaf' 카테고리의 다른 글
[Thymeleaf] 스프링 통합과 폼 (0) | 2024.03.09 |
---|---|
[Thymeleaf] 타임리프 레이아웃 (0) | 2024.03.08 |
[Thymeleaf] 템플릿 조각 (0) | 2024.03.07 |
[Thymeleaf] 타임리프 기본 기능 (1) | 2024.03.06 |