타임리프(Thymeleaf)
thymeleaf-spring6
thymeleaf - java8time // JDK8 Date & TIME API -> #temporals : 형식화
thymeleaf layout :레이아웃 기능
package org.choongang.config;
import lombok.RequiredArgsConstructor;
import nz.net.ultraq.thymeleaf.layoutdialect.LayoutDialect;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.thymeleaf.extras.java8time.dialect.Java8TimeDialect;
import org.thymeleaf.spring6.SpringTemplateEngine;
import org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring6.view.ThymeleafViewResolver;
@Configuration
@RequiredArgsConstructor
public class ThymeleafConfig implements WebMvcConfigurer {
private final WebApplicationContext applicationContext;
@Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(applicationContext);
templateResolver.setPrefix("/WEB-INF/templates2/");
templateResolver.setSuffix(".html");
templateResolver.setCacheable(false);
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.setEnableSpringELCompiler(true);
templateEngine.addDialect(new Java8TimeDialect());
templateEngine.addDialect(new LayoutDialect());
return templateEngine;
}
@Bean
public ThymeleafViewResolver thymeleafViewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setContentType("text/html");
resolver.setCharacterEncoding("utf-8");
resolver.setTemplateEngine(templateEngine());
return resolver;
}
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.viewResolver(thymeleafViewResolver());
}
}
- Natural Template
- 원래 HTML과 서버사이드 렌더링 결과 거의 동일하게 보이는 효과
- 번역 기술
- 캐시 기능 제공
1) 변수 식 : ${변수, 연산..}
2) 메세지 식 : #{메세지 코드}
<-> <spring:message code="..">
참고)
fmt:setBundle
<fmt:message key="메세지 코드">
3) 링크 식 : @{주소}
- 컨텍스트 경로 추가
- URL 변수 식, 요청 파라미터 쉽게 추가
참고)
-> <c:url value="...." />
4) 선택 변수식
th:object="${객체}"
*{속성명}
th:text="*{속성명}" == ${객체.속성명}
html에서 번역될 때 사라짐
1) #strings
2) #numbers
3) #dates, #calendars, #temporals : (java 8, java.time 패키지)
4) #lists, #sets, #maps
-> 내장 식객체에 없는 기능? 스프링 빈으로 생성
${@빈이름.메서드명(...)}
-반복문
status 변수명은 변경 가능.
th:if : 조건식
th:if="${....}"
th:unless="${...}" : 조건식이 false -> 노출, true -> 노출 X
true, false -> 상수로 바로 인식
th:src
th:action
두개도 가능
<a th:href="@{/member/info/{email}/{email2}(email=*{email}, email2=*{userName})}"></a>
-클래스를 조건에 따라 추가 제거하는 문법
th:classappend="{조건식} ? "참일때" : "거짓일때"
-특정 필드에 한정한 오류 출력(email, password ..)
커맨드 객체 있는 애노테이션 검증(@NotBlank..)
- Errors::rejectValue("필드명","에러코드")
// validator에서
if (StringUtils.hasText(confirmPassword) && !password.equals(confirmPassword)) {
errors.rejectValue("confirmPassword", "Mismatch");
}
-다만 global 필드이면 Global Error 출력
-Global Error 출력 용도
- Errors::reject("에러코드")
th:field="*{속성명}"
참고)
#이 붙어 있는 경우 -> 식 객체(내장 객체)
<form:errors path="..." />
타임리프 페이지 레이아웃
th:replace : 템플릿 파일 치환
th:fragment
#temporals: java.time 패키지 관련 형식화 및 편의 메서드가 정의된 식 객체
#concat 문자열 결합
#numbers.formatInteger
#numbers.sequence
#빈 메서드 접근
${@빈이름.메서드명(..)}
*{@빈이름,메서드명(..)}
내용이 치환됨