타임리프
- 순수 HTML 그대로 유지,뷰 템플릿 사용=> 네츄럴 템플릿
<html xmlns:th="http://www.thymeleaf.org">
텍스트
model.addAttribute("data", "Hello Spring!");
<span th:text="${data}">
<li>[[${data}]]</li> //직접
- 기본적으로 이스케이프 제공: th:text, [[...]]
- 이스케이프x: th:utext, [(...)]
변수 - SpringEL
model.addAttribute("user", userA);
model.addAttribute("users", list);
model.addAttribute("userMap", map);
th:text="${user.username}"
th:text="${users[0].username}"
th:text="${userMap['userA'].username}"
//지역변수
th:with="first=${users[0]}"
th:text="${first.username}"
기본 객체
- 기본 객체: ${#request},${#response},${#session},${#servletContext},${#locale}
- 편의 객체
session.setAttribute("sessionData", "Hello Session");
${session.sessionData}
@Component("helloBean")
${@helloBean.hello('Spring!')}
${param.paramData}
유틸리티 객체와 날짜
model.addAttribute("localDateTime", LocalDateTime.now());
th:text="${#temporals.format(localDateTime, 'yyyy-MM-dd HH:mm:ss')}"
th:text="${#temporals.day(localDateTime)}"
URL 링크
- 단순 URL: th:href="@{/hello}"
- 쿼리 파라미터: th:href="@{/hello(param1=${param1}, param2=${param2})}"
- 경로 변수: {param1}(param1=${param1})
리터럴
- 고정된 값
- 문자열 공백 ''로 감싸기
<span th:text="'hello world!'"></span>
//리터럴 대체
model.addAttribute("data", "Spring!");
<span th:text="|hello ${data}|"></span>
연산
th:text="10 + 2"
th:text="1 gt 10"
<span th:text="${nullData}?: '데이터가 없습니다.'"></span></li>
<span th:text="${nullData}?: _">데이터가 없습니다.</span></li>
//타임리프가 실행되지 않는 것 처럼 동작
속성 값 설정
- 속성추가
th:attrappend="class='large'" 앞
th:attrprepend="class='large'" 뒤
th:classappend="large"
th:checked="true"
반복
model.addAttribute("users", list);
<tr th:each="user : ${users}">
<td th:text="${user.username}">username</td>
<td th:text="${user.age}">0</td>
</tr>
// 상태확인(userStat 생략가능)
<tr th:each="user, userStat : ${users}">
<span th:text="${userStat.index}"></span>
조건부 평가
//참인경우 출력
<span th:text="'미성년자'" th:if="${user.age lt 20}"></span>
<span th:text="'미성년자'" th:unless="${user.age ge 20}"></span>
<td th:switch="${user.age}">
<span th:case="10">10살</span>
<span th:case="20">20살</span>
<span th:case="*">기타</span>
</td>
블록
- <th:block th:each="user : ${users}">
- 애매한 경우
자바스크립트 인라인
- 타입 변환, 이스케이브, 객체 json 변환
//each
<script th:inline="javascript">
[# th:each="user, stat : ${users}"]
var user[[${stat.count}]] = [[${user}]];
[/]
</script>
템플릿 조각
<footer th:fragment="copyParam (param1)">
<p th:text="${param1}"></p>
</footer>
->다른 파일에 합쳐짐
//합칠 조각의 위치::조각 이름(파라미터)
<div th:replace="~{template/fragment/footer :: copyParam ('데이터1')}"></div>
//단순표현
<div th:replace="template/fragment/footer :: copy"></div>
템플릿 레이아웃
//베이스
<head th:fragment="common_header(title,links)">
<title th:replace="${title}">레이아웃 타이틀</title>
~~~공통부분~~~
<th:block th:replace="${links}" />
</head>
//메인
<head th:replace="template/layout/base :: common_header(~{::title},~{::link})">
<title>메인 타이틀</title>
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
-> 컨트롤러는 메인을 호출 메인에서 베이스로 바꿀 부분만 넘겨서 가져와
타임리프 - 스프링 통합과 폼
입력 폼 처리
model.addAttribute("item", new Item());
th:object="${item}"
th:field="*{itemName}"//선택 변수 식 ->${item.itemName}
->field가 id="itemName" name="itemName" th:value="*{itemName}" 만들어줌
체크박스 -단일
<input type="checkbox" id="open" name="open" class="form-check-input">
<input type="hidden" name="_open" value="on"/> //체크 해제 인식
//타임리프 hidden 자동생성
<input type="checkbox" id="open" th:field="*{open}" class="form-check-input">
체크박스 -멀티
- 컨트롤러에 있는 별도의 메서드에 적용: @ModelAttribute("regions")
th:each="region : ${regions}" //map
type="checkbox" th:field="*{regions}" th:value="${region.key}"
th:for="${#ids.prev('regions')}" th:text="${region.value}"
라디오 버튼
@ModelAttribute("itemTypes")
th:each="type : ${itemTypes}" //ENUM-배열
type="radio" th:field="*{itemType}" th:value="${type.name()}"
th:for="${#ids.prev('itemType')}" th:text="${type.description}"
- 히든 필드 사용할 필요 없음
셀렉트 박스
@ModelAttribute("deliveryCodes")
<select th:field="*{deliveryCode}" class="form-select"> //객체 "${item.deliveryCode}"
<option value="">==배송 방식 선택==</option>
<option th:each="deliveryCode : ${deliveryCodes}" th:value="${deliveryCode.code}"
th:text="${deliveryCode.displayName}">FAST</option>
</select>
메시지, 국제화
- messages.properties(기본) / messages_en.properties
- item.itemName=상품명 {0} / item.itemName=Item Name {0}
- th:text="#{item.itemName(${item.itemName})}"
- ResourceBundleMessageSource 빈 등록
setBasenames("messages", "errors"); setDefaultEncoding("utf-8");
- 스프링 부트 MessageSource자동 등록
- spring.messages.basename=messages
- {0}:매개변수 ms.getMessage("item.itemName", new Object[]{"안녕"}, null);->상품명 안녕
- 국제화 파일 선택 ms.getMessage("item.itemName", null, Locale.ENGLISH)->Item Name
링크
'스프링' 카테고리의 다른 글
로그인 (0) | 2022.06.18 |
---|---|
검증 (0) | 2022.06.17 |
[스프링] 스프링 MVC (0) | 2022.06.09 |
[스프링] MVC 프레임워크 (0) | 2022.06.09 |
[스프링] 서블릿, JSP, MVC 패턴 (0) | 2022.06.09 |