오늘은 게시판 프로젝트를 수정해보면서 Tymeleaf를 처음 접하게되었다.
현재 타임리프를 사용하여 form태그로 비밀번호 일치 확인하는 로직을 작성하고 있는데
생각보다 쉽지 않아서 골머리를 싸고있다.
그래도 Thymeleaf를 사용함으로서 코드가 확실히 줄어들고 한눈에 알아보기 쉬워서 유용하게 쓸 것 같다.
Thymeleaf란?
'템플릿 엔진'의 일종. html 태그에 속성을 추가해 페이지에 동적으로 값을 추가하거나 처리할 수 있다.
Thymeleaf 문법
대부분의 html 속성을 th:xxx 로 변경할 수 있다.
ex: th:text="${변수명}"
표현 | 설명 | 예제 |
@{ ... } | URL 링크 표현식 | th:href="@{/css/bootstrap.min.css}" th:href="@{/{itemId}/edit(itemId=${item.id})}" |
| ... | | 리터럴 대체 | th:text="|Hi ${user.name}!|" (= th:text="'Hi '+${user.name}+'!'" |
${ ... } | 변수 | th:text=${user.name} |
th:each | 반복 출력 | <tr th:each="item: ${items}"> <td th:text="${item.price}">100</td> </tr> |
*{ ... } | 선택 변수 | <tr th:object="${items}"> <td th:text="*{price}">100</td> </tr> |
#{ ... } | 메시지. properties 같은 외부 자원에서 코드에 해당하는 문자열 get. | th:text="#{member.register}" |
xmlns:th
- 타임리프의 th속성을 사용하기 위해 선언된 네임스페이스이다.
- 순수 HTML로만 이루어진 페이지의 경우, 선언하지 않아도 무관하다.
th:text
- JSP의 EL 표현식인 ${}와 마찬가지로 타임리프도 ${} 표현식을 사용해서 컨트롤러에서 전달받은 데이터에 접근할 수 있다.
- 해당 속성은 일반적인 텍스트 형식으로 화면에 출력한다.
th:fragment
- <head>태그에 해당 속성을 사용해서 fragment의 이름을 지정한다.
- fragment는 다른 HTML에서 include 또는 replace 속성을 사용해서 적용할 수 있다.
th:block
- layoutL:fragment 속성에 이름을 지정해서 실제 Content 페이지의 내용을 채우는 기능이다.
- 해당 기능은 동적(Dynamic)인 처리가 필요할 때 사용된다.
th:replace
- JSP의 <include> 태그와 유사한 속성이다.
- th:fragment을 통해 설정한 이름을 찾아 해당 코드로 치환한다.
th:href
- <a> 태그의 href 속성과 동일하다.
- 웹 애플리케이션을 구분하는 콘텍스트 경로(Context Path)를 포함한다.
xmlns:layout, xmlnslayout:decorator
- xmlns:layout은 타임리프의 레이아웃 기능을 사용하기 위한 선언이다.
- xmlnslayout:decorator 레이아웃으로 basic.html을 사용하겠다는 의미이다.
Gradle 추가
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect' /* Thymeleaf Layout */
선언방법
<html lang="ko" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorator="board/layout/basic">
위의 방식 오류
2021-11-21 17:08:00.095 WARN 22472 --- [nio-8080-exec-1] n.n.u.t.decorators.DecoratorProcessor : The layout:decorator/data-layout-decorator processor has been deprecated and will be removed in the next major version of the layout dialect.
해결
layout:decorator="board/layout/basic" 을
layout:decorate="~{board/layout/basic} 으로 변경
즉, 아래의 코드처럼 변경 해야 한다.
<html lang="ko" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{board/layout/basic}">
th:block layout:fragment
- layout:fragment 속성에 이름을 지정해서 실제 Content 페이지의 내용을 채우게 된다.
- 에를 들어 글쓰기 페이지는 "write page"로, 게시글 리스트 페이지는 "list page" 이런식 이다.
- 즉, 페이지마다 타이틀을 다르게 처리하고 싶을 때 해당 속성을 이용해서 타이틀을 동적(Dynamic)으로 처리할 수 있다.
th:action
- <form>태그 사용시 해당 경로로 요청을 보낼때 사용한다.
th:object
- <form>태그에서 submit을 할 때, 데이터가 th:object에 설정해둔 객체로 받아진다.
- 즉, 컨트롤러와 뷰(화면) 사이의 DTO클래스의 객체이다.
<form class="form-horizontal" th:action="@{/board/register.do}" th:object="${board}" method="post">
th:field
- 위의 th:object 속성을 이용하면, th:field를 이용해서 HTML 태그에 멤버 변수를 매핑 할 수 있다.
- th:field을 이용한 사용자 입력 필드(input, textarea 등)는 id, name, value 속성 값이 자동으로 매핑된다.
- 그렇기에, 각 속성을 따로 지정할 필요가 없다.
- th:field는 ${}표현식이 아닌, *{}표현식을 사용한다.
- th:object와 th:field는 컨트롤러에서 특정 클래스의 객체를 전달 받은 경우에만 사용 가능하다.
<input type="text" th:field="*{title}" class="form-control" placeholder="제목을 입력해 주세요." />
th:checked
- 체크박스의 경우, th:checked 속성을 이용해서 조건이 "true"에 해당하면, checked 속성을 적용한다.
th:inline="javascript"
- <script> 태그에 th:inline 속성을 javascript로 지정해야 자바스크립트를 사용할 수 있다.
th:if, th:unless
- th:if는 if 문과 동일하고, th:unless는 else 문과 같다고 볼 수 있다.
- th:unless는 일반적인 언어의 else 문과는 달리 th:if에 들어가는 조건과 동일한 조건을 지정해야 한다.
th:each
- th:each는 JSTL의 <c:foreach>, 자바의 forEach와 유사한 기능이다.
th URI GET 파라미터 추가 방식
- 일반적인 GET 파라미터 추가 방식
/board/view.do?idx=${idx}&page=${page}
- 타임리프 GET 파라미터 추가 방식
/board/view.do(idx=${idx},page=${page}
<![CDATA[]]>
- 타임리프는 '<','> '태그를 엄격하게 검사하기 때문에 자바스크립트 코드는 꼭 CDATA로 묶어줘야 한다.
- CDATA는 특수문자를 전부 문자열로 치환할 때 사용한다.
@출처 : https://myeongdev.tistory.com/20
@출처 :https://yeonyeon.tistory.com/153
'내일배움캠프 > Today I Learned' 카테고리의 다른 글
[TIL] 나의 스물아홉번째 회고록 (0) | 2022.12.15 |
---|---|
[TIL] 나의 스물 여덟번째 회고록 (0) | 2022.12.14 |
[내배캠] 스물 여섯번째 회고록 (0) | 2022.12.11 |
[내배캠] 나의 스물 다섯번째 회고록 (0) | 2022.12.09 |
[내배캠] 나의 스물네번째 회고록 (0) | 2022.12.08 |