thymeleaf-basic
??
//
#타임리프 기본 사용법
기본 문법
• 간단한 표현:
ㅤ ◦ 변수 표현식: ${...}
ㅤ ◦ 선택 변수 표현식: *{...}
ㅤ ◦ 메시지 표현식: #{...}
ㅤ ◦ 링크 URL 표현식: @{...}
ㅤ ◦ 조각 표현식: ~{...}
• 리터럴
ㅤ ◦ 텍스트: 'one text', 'Another one!',…
ㅤ ◦ 숫자: 0, 34, 3.0, 12.3,…
ㅤ ◦ 불린: true, false
ㅤ ◦ 널: null
ㅤ ◦ 리터럴 토큰: one, sometext, main,…
• 문자 연산:
ㅤ ◦ 문자 합치기: +
ㅤ ◦ 리터럴 대체: |The name is ${name}|
• 산술 연산:
ㅤ ◦ Binary operators: +, -, *, /, %
ㅤ ◦ Minus sign (unary operator): -
• 불린 연산:
ㅤ ◦ Binary operators: and, or
ㅤ ◦ Boolean negation (unary operator): !, not
• 비교와 동등:
ㅤ ◦ 비교: >, <, >=, <= (gt, lt, ge, le)
ㅤ ◦ 동등 연산: ==, != (eq, ne)
• 조건 연산:
ㅤ ◦ If-then: (if) ? (then)
ㅤ ◦ If-then-else: (if) ? (then) : (else)
ㅤ ◦ Default: (value) ?: (defaultvalue)
• 특별한 토큰:
ㅤ ◦ No-Operation: _
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#standard-expression-syntax
text, utext
- text : Controller에서 받은 문자 그대로 출력 (자동 Escape)
escape (문자 그대로 변환시키기 위해 html Tag 등에 들어가는
특수 문자들을 다르게 치환하는 것)Hello Spring! ->
ex)Hello <b> Spring ! </b>
Text Escape
<li>th:text사용<span th:text="${data}"></span></li>
<li>컨텐츠 안에서 직접 출력하기 = [[${data}]]</li>
- utext : Unescape하여 태그가 있으면 htmlEntity로 변환하여 출력
UText Unescape
<li>th:utext사용<span th:utext="${data}"></span></li>
<li>컨텐츠 안에서 직접 출력하기 = [(${data})]</li>
변수 - SpringEL
- Object, List, Map 표현 방법
<ul>Object
<li>${user.username} = <span th:text="${user.username}"></span></li>
<li>${user['username']} = <span th:text="${user['username']}"></span></li>
<li>${user.getUsername()} = <span th:text="${user.getUsername()}"></span></li>
</ul>
<ul>List
<li>${users[0].username} = <span th:text="${users[0].username}"></span></li>
<li>${users[0]['username']} = <span th:text="${users[0]['username']}"></span></li>
<li>${users[0].getUsername()} = <span th:text="${users[0].getUsername()}"></span></li>
</ul>
<ul>Map
<li>${userMap['userA'].username} = <span th:text="${userMap['userA'].username}"></span></li>
<li>${userMap['userA']['username']} = <span th:text="${userMap['userA']['username']}"></span></li>
<li>${userMap['userA'].getUsername()} = <span th:text="${userMap['userA'].getUsername()}"></span></li>
</ul>
지역변수 with
- 지역 변수 선언
- 선언된 태그 안에서만 사용 가능하다.
<h1>지역 변수 - (th:with)</h1>
<div th:with="first=${user[0]}">
<p>처음 사람의 이름은 <span th:text="${first.username}"></span></p>
</div>
-- first란 지역변수에 user[0]을 삽입하여 사용.
기본객체
Thymeleaf는 기본적으로 request, response, session, servletContext, local을 제공한다.
<ul>
<li>request = <span th:text="${#request}"></span></li>
<li>response = <span th:text="${#response}"></span></li>
<li>session = <span th:text="${#session}"></span></li>
<li>servletContext = <span th:text="${#servletContext}"></span></li>
<li>locale = <span th:text="${#locale}"></span></li>
</ul>
기본 객체가 잡힌 모습
- 기본 주어진 객체에서 data를 꺼내서 쓸 수도 있겠지만, 이도 편리하게 이미 구현되어있다.
<ul>
<li>Request Parameter = <span th:text="${param.paramData}"></span></li>
<li>session = <span th:text="${session.sessionData}"></span></li>
<li>spring bean = <span th:text="${@helloBean.hello('Spring!')}"></span></li>
</ul>
편의객체들
- request에 Parameter를 기본적으로 꺼내 쓸 수 있는 param
ex ) http://localhost:8090/basic/basic-objects?paramData=HelloParam 으로 paramData에 HelloParam을 넣은 모습
- session에 담긴 key값으로 데이터 꺼내기
@GetMapping("/basic-objects")
public String basicObjects(HttpSession session) {
session.setAttribute("sessionData", "Hello Session");
return "basic/basic-objects";
}
- 심지어 bean도 호출하여 method를 그릴 수도 있다.
@Component("helloBean")
static class HelloBean {
public String hello(String data) {
return "Hello " + data;
}
}
기본 편의 utils
타임리프 유틸리티 객체들
- message : 메시지, 국제화 처리
- uris : URI 이스케이프 지원
- dates : java.util.Date 서식 지원
- calendars : java.util.Calendar 서식 지원
- temporals : 자바8 날짜 서식 지원
- numbers : 숫자 서식 지원
- strings : 문자 관련 편의 기능
- objects : 객체 관련 기능 제공
- bools : boolean 관련 기능 제공
- arrays : 배열 관련 기능 제공
- lists , sets , maps : 컬렉션 관련 기능 제공
- ids : 아이디 처리 관련 기능 제공, 뒤에서 설명
★필요한 java 8의 LocalDate, LocalDateTime, instant
<ul>
<li>default = <span th:text="${localDateTime}"></span></li>
<li>yyyy-MM-dd HH:mm:ss = <span th:text="${#temporals.format(localDateTime, 'yyyy-MM-dd HH:mm:ss')}"></span></li>
</ul>
<h1>LocalDateTime - Utils</h1>
<ul>
<li>${#temporals.day(localDateTime)} = <span th:text="${#temporals.day(localDateTime)}"></span></li>
<li>${#temporals.month(localDateTime)} = <span th:text="${#temporals.month(localDateTime)}"></span></li>
<li>${#temporals.monthName(localDateTime)} = <span th:text="${#temporals.monthName(localDateTime)}"></span></li>
<li>${#temporals.monthNameShort(localDateTime)} = <span th:text="${#temporals.monthNameShort(localDateTime)}"></span></li>
<li>${#temporals.year(localDateTime)} = <span th:text="${#temporals.year(localDateTime)}"></span></li>
<li>${#temporals.dayOfWeek(localDateTime)} = <span th:text="${#temporals.dayOfWeek(localDateTime)}"></span></li>
<li>${#temporals.dayOfWeekName(localDateTime)} = <span th:text="${#temporals.dayOfWeekName(localDateTime)}"></span></li>
<li>${#temporals.dayOfWeekNameShort(localDateTime)} = <span th:text="${#temporals.dayOfWeekNameShort(localDateTime)}"></span></li>
<li>${#temporals.hour(localDateTime)} = <span th:text="${#temporals.hour(localDateTime)}"></span></li>
<li>${#temporals.minute(localDateTime)} = <span th:text="${#temporals.minute(localDateTime)}"></span></li>
<li>${#temporals.second(localDateTime)} = <span th:text="${#temporals.second(localDateTime)}"></span></li>
<li>${#temporals.nanosecond(localDateTime)} = <span th:text="${#temporals.nanosecond(localDateTime)}"></span></li>
</ul>
@GetMapping("/date")
public String date(Model model) {
model.addAttribute("localDateTime", LocalDateTime.now());
return "basic/date";
}
JAVA8의 LocalDateTime을 다루는 많은 방법들
URL 링크다는 방법
기본적으로 "@{}"사이에 변수던, path던 입력하면 된다.
화면
<ul>
//일반 URL
<li><a th:href="@{/hello}">basic url</a></li>
//QueryParam
<li><a th:href="@{/hello(param1=${param1}, param2=${param2})}">hello query param</a></li>
//PathVariable
<li><a th:href="@{/hello/{param1}/{param2}(param1=${param1}, param2=${param2})}">path variable</a></li>
//PathVariable + QueryParam
<li><a th:href="@{/hello/{param1}(param1=${param1}, param2=${param2})}">path variable + query parameter</a></li>
</ul>
Controller
@GetMapping("link")
public String link(Model model) {
model.addAttribute("param1", "data1");
model.addAttribute("param2", "data2");
return "basic/link";
}
- Controller에서 data를 받아 PathVariable을 구현할 수도 있고, {변수}를 선언하지 않고 추가적으로 붙이면 QueryParam으로 붙는다.
링크가 생성된 모습
기본 편의 utils
타임리프 유틸리티 객체들
- message : 메시지, 국제화 처리
- uris : URI 이스케이프 지원
- dates : java.util.Date 서식 지원
- calendars : java.util.Calendar 서식 지원
- temporals : 자바8 날짜 서식 지원
- numbers : 숫자 서식 지원
- strings : 문자 관련 편의 기능
- objects : 객체 관련 기능 제공
- bools : boolean 관련 기능 제공
- arrays : 배열 관련 기능 제공
- lists , sets , maps : 컬렉션 관련 기능 제공
- ids : 아이디 처리 관련 기능 제공, 뒤에서 설명
필요한 java 8의 LocalDate, LocalDateTime, instant
리터럴 (고정 문자 그대로 보여주기)
기본적으로 공백 없이 이어서 붙이면 타임리프가 그대로 보여주는데, 공백이나 특수문자가 생길 경우가 문제가 된다.
화면
<ul>
<li>'hello' + ' world!' = <span th:text="'hello' + ' world!'"></span></li>
<li>'hello world!' = <span th:text="'hello world!'"></span></li>
<li>'hello ' + ${data} = <span th:text="'hello ' + ${data}"></span></li>
<li>리터럴 대체 |hello ${data}| = <span th:text="|hello ${data}|"></span></li>
</ul>
- 요즘은 주로 리터럴 대체문자로 || 내부에 편리하게 이어서 작성하기가 사용된다.
- 단순히 ""만 사용하면 Pasing 에러가 나므로 숙지해두길!
타임리프 기본 연산
- 내부에서 기본적인 비교, 연산은 가능하다.
기본 연산
<li>산술 연산
<ul>
<li>10 + 2 = <span th:text="10 + 2"></span></li>
<li>10 % 2 == 0 = <span th:text="10 % 2 == 0"></span></li>
</ul>
</li>
<li>비교 연산
<ul>
<li>1 > 10 = <span th:text="1 > 10"></span></li>
<li>1 gt 10 = <span th:text="1 gt 10"></span></li>
<li>1 >= 10 = <span th:text="1 >= 10"></span></li>
<li>1 ge 10 = <span th:text="1 ge 10"></span></li>
<li>1 == 1 = <span th:text="1 == 10"></span></li>
<li>1 != 1 = <span th:text="1 != 10"></span></li>
</ul>
</li>
조건부 출력
- 기본 삼항연산자
<li>조건식
<ul>
<li>(10 % 2 == 0)? '짝수':'홀수' = <span th:text="(10 % 2 == 0)? '짝수':'홀수'"></span></li>
</ul>
</li>
- Elvis 연산자
<li>Elvis 연산자
<ul>
<li>${data}?: '데이터가 없습니다.' = <span th:text="${data}?: '데이터가 없습니다.'"></span></li>
--null이면 오른쪽 '데이터가 없습니다' 가 출력된다.
<li>${nullData}?: '데이터가 없습니다.' = <span th:text="${nullData}?: '데이터가 없습니다.'"></span></li>
</ul>
</li>
- No-Operation
_
을 입력하여 null이 들어오면 해당 태그를 타임리프를 무효화하고 기본 html이 출력되게 한다.
<li>No-Operation
<ul>
<li>${data}?: _ = <span th:text="${data}?: _">데이터가 없습니다.</span></li>
<li>${nullData}?: _ = <span th:text="${nullData}?: _">데이터가 없습니다.</span></li>
</ul>
</li>
- Controller에서 값 받아서 조건문 생성하기
<li>test
<ul>
<li>${test1} > ${test2}<span th:text="${test1} > ${test2}"></span></li>
</ul>
</li>
@GetMapping("/operation")
public String operation(Model model) {
model.addAttribute("nullDate", null);
model.addAttribute("data", "Spring!");
model.addAttribute("test1", 1);
model.addAttribute("test2", 2);
return "basic/operation";
}
html이 1>2 false로 잘 출력된 모습
Attribute 설정,추가
- 속성 설정
화면
- 그냥 th가 덮어쓴다.
<input type="text" name="mock" th:name="userA" />
<input type="text" name="mock" th:name="${data}" />
- 속성 추가
화면
- class 명의 앞, 뒤에 추가
//띄어쓰기 신경
- th:attrappend = <input type="text" class="text" th:attrappend="class=' large'" /><br/>
- th:attrprepend = <input type="text" class="text" th:attrprepend="class='large '" /><br/>
//띄어쓰기 알아서 해줌
- th:classappend = <input type="text" class="text" th:classappend="large" /><br/>
checkbox 체크, 해제 처리
화면
html은 값과 상관없이 checked 속성만 있으면 checkbox를 check한다.
타임리프의 th:checked는 false인 경우 checked 속성을 제거한다.
Controller에서 isChecked 불린 값을 넘겨서 처리하면 되므로 개발자가 개발하기 편해진다.
- checked o <input type="checkbox" name="active" th:checked="${isChecked}" /><br/>
- checked x <input type="checkbox" name="active" th:checked="${isChecked}" /><br/>
- checked=false <input type="checkbox" name="active" checked="false" /><br/>
//
if, unless 조건
화면
- 조건을 만족하지 않으면 태그 자체를 무효화한다.
- 예제에서는 유저 나이 조건
<tr th:each="user, userStat : ${users}">
<td th:text="${userStat.count}">1</td>
<td th:text="${user.username}">username</td>
<td>
<span th:text="${user.age}">0</span>
<span th:text="'미성년자'" th:if="${user.age lt 20}"></span> 20살 lessthan
<span th:text="'미성년자'" th:unless="${user.age ge 20}"></span> 20살 이상이 아니면
</td>
</tr>
###
block 태그 (타임리프 유일)
화면
<th:block th:each="user : ${users}">
<div>
사용자 이름1 <span th:text="${user.username}"></span>
사용자 나이1 <span th:text="${user.age}"></span>
</div>
<div>
요약 <span th:text="${user.username} + ' / ' + ${user.age}"></span>
</div>
</th:block>
- 전체를 긁어서 반복을 돌리고 싶을 때 사용한다. (each만으로 해결하기 어려울 때)
Template으로 조각내어 파일 관리
ex) Footer 파일을 따로 분리하여 관리하기
<footer th:fragment="copy">
푸터 자리 입니다.
</footer>
<footer th:fragment="copyParam (param1, param2)">
<p>파라미터 자리 입니다.</p>
<p th:text="${param1}"></p>
<p th:text="${param2}"></p>
</footer>
- th:fragment로 이름 선언하여 해당 컴포넌트 작성
<body>
<h1>부분 포함</h1>
<h2>부분 포함 insert</h2>
<div th:insert="~{template/fragment/footer :: copy}"></div>
div 태그 내부에 insert <div><인서트></div>
<h2>부분 포함 replace</h2>
<div th:replace="~{template/fragment/footer :: copy}"></div>
div 자체도 아예 replace
<h2>부분 포함 단순 표현식</h2>
<div th:replace="template/fragment/footer :: copy"></div>
<h1>파라미터 사용</h1>
<div th:replace="~{template/fragment/footer :: copyParam ('데이터1', '데이터2')}"></div>
</body>
붙여놓길 원하는 html파일에서 th:insert, th:replace 이용하여 {경로 :: 이름} 삽입
th:insert는 외부 태그 안에 삽입
th:replace는 외부 태그 자체를 교체
메서드처럼 파라미터도 받을 수 있다.
Template 조각이 아닌, 통짜 파일 삽입
교체용 Header template
<head th:fragment="common_header(title,links)">
<title th:replace="${title}">레이아웃 타이틀</title>
<!-- 공통 -->
<link rel="stylesheet" type="text/css" media="all" th:href="@{/css/awesomeapp.css}">
<link rel="shortcut icon" th:href="@{/images/favicon.ico}">
<script type="text/javascript" th:src="@{/sh/scripts/codebase.js}"></script>
<!-- 추가 -->
<th:block th:replace="${links}" />
</head>
- th:fragment="common_header(title,links)"를 선언하여 이게 fragment 교체용 템프릿이고, common_header의 id와 title,links 인자를 받는다고 선언
- 인자로 받은 title, links는 th:replace로 교체
Template 사용 예제
<head th:replace="template/layout/base :: common_header(~{::title},~{::link})">
<title>메인 타이틀</title>
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
<link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}">
</head>
- th:replace="template/layout/base :: common_header(
{::title},{::link})"로 해당경로의 :: common_header 이름의 Template 소환, - ~{::title}로 내 title, link를 인자로 전송하여 Template에서 th:replace 시켜서 소스 변환.
마찬가지로 html에 선언해서 통짜 html Template을 생성할 수도 있다.
'스프링' 카테고리의 다른 글
[Spring AOP] 2.ProxyFactory로 대상에 따른 기술에 구애받지 않고 Proxy 생성,적용하기 (Advisor, Advice, PointCut) (0) | 2022.11.16 |
---|