jsp처럼) HTML을 동적으로 렌더링하는 용도로 사용된다.${...} : 변수 표현식 *{...} : 선택 변수표현식 #{...} : 메시지 표현식 @{...} : 링크 URL 표현식 ~{...} : 조각 표현식 +|The Name is ${name}|+ , - , * , / , %and , or , ! , not > , < , >= , <= (gt, lt, ge, le)== , != (eq,ne)if-then , if-then-else[[${data}]]<span th:text="${data}"></span>[(${data})]<span th:utext="${data}"></span>
- 출력 예시
<span th:text="${user.username}"></span><span th:text="${user['username']}"></span><span th:text="${user.getUsername()}"></span><span th:text="${users[0].username}"></span><span th:text="${userMap['userA'].username}"></span><div th:with="first=${users[0]}"> <p>처음 사람의 이름은 <span th:text=${first.username}></span></p> </div> <div th:with="second=${users[1]}"> <p>처음 사람의 이름은 <span th:text=${second.username}></span></p> </div>
${#객체명} (예 : ${#request})
- 출력 예시
<h1>식 기본 객체</h1> <ul> <li>request = <span th:text="${#request}"></span></li> <li>response = <span th:text="${#response}"></span></li> // session은 컨트롤러에서 HttpSession을 파라미터로 전달받아야 생성됨 <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>
<span th:text="${#request.getParameter('paramData')}"></span><span th:text="${param.paramData}"></span><span th:text="${session.sessionData}"></span>@Component("helloBean") public class HelloBean { public String hello(String data) { return "spring data " + data; } }
<span th:text="${@helloBean.hello('user')}"></span>
<span th:text="${localDateTime}"></span><span th:text="${#temporals.format(localDateTime,'yyyy-MM-dd HH:mm:ss')}"></span>

@{/hello} /hello@{/hello(param1=${param1}, param2=${param2})} /hello?param1=data1¶m2=data2@{/hello/{param1}/{param2}(param1=${param1},param2=${param2})}/hello/data1/data2@{/hello/{param1}(param1=${param1},param2=${param2})}/hello/data1?param2=data2''(작은 따옴표)로 감싸야 한다.<span th:text="'hello'">''로 감싸는 것은 번거롭기 때문에 공백 없이 이어진다면 하나의 의미 있는 토큰으로 인지하여 다음과 같이 작은 따옴표를 생략 가능하다.<span th:text="hello"><span th:text="hello world"> (오류)<span th:text="'hello world'"> (정상동작) +연산자를 사용할 수도 있지만, 리터럴 대체||를 사용하면 생략 가능하다.+ : <span th:text="'hello ' + ${data}"></span>|| : <span th:text="|hello ${data}|"></span><span th:text="10 + 2"> -> 결과 : 12<span th:text="1 gt 10"></span> -> 결과 : false<span th:text="(10 % 2 == 0)?'짝수':'홀수'"></span> -> 결과 : 짝수<span th:text="${Data}?: '데이터가 없습니다.'"></span><span th:text="${Data}?:_">데이터가 없습니다.</span><input type="text" name="mock" th:name="userA">th:attrappend : 속성 값 뒤에 값을 추가th:attrprepend : 속성 값 앞에 값을 추가th:classappend : class 속성에 추가<input type="text" class="text" th:attrappend="class='large'"> // 결과 class="textlarge" <input type="text" class="text" th:attrprepend="class='large'"> // 결과 class="largetext" <input type="text" class="text" th:classappend="large"> // 결과 class="text large"
th:checked 속성은 true, false로 설정한다.<input type="checkbox" name="active" th:checked="false">th:each로 반복문을 구현한다.// users - 객체들로 이루어진 list <tr th:each="user: ${users}"> <td th:text="${user.username}">username</td> <td th:text="${user.age}">0</td> </tr>
지정한 변수명+Stat가 된다.<tr th:each="user, userStat : ${users}"> <td th:text="${userStat.count}">0</td> <td th:text="${user.username}">username</td> <td th:text="${user.age}">0</td> <td> index = <span th:text="${userStat.index}"></span> / count = <span th:text="${userStat.count}"></span> / size = <span th:text="${userStat.size}"></span> / even = <span th:text="${userStat.even}"></span> / odd = <span th:text="${userStat.odd}"></span> / first = <span th:text="${userStat.first}"></span> / last = <span th:text="${userStat.last}"></span> </td> </tr>
if / unless
: if는 조건 충족, unless는 조건 불충족 시에 실행된다.
타임리프는 해당 조건이 맞지 않으면 태그 자체를 렌더링하지 않는다.
<tr th:each="user,userStat : ${users}"> <td th:text=${userStat.count}>count</td> <td th:text=${user.username}>username</td> <td> <span th:text="${user.age}"></span> // if, unless 평가 <span th:text="'미성년자'" th:if="${user.age lt 20}"></span> <span th:text="'성인'" th:unless="${user.age lt 20}"></span> </td> </tr>
switch
조건을 만족하지 않으면 해당 tag가 조회되지 않는다.
<tr th:each="user,userStat : ${users}"> <td th:text=${userStat.count}>count</td> <td th:text=${user.username}>username</td> <td th:switch="${user.age}"> <span th:case="10">10살</span> <span th:case="20">20살</span> <span th:case="*">기타</span> </td> </tr>
<!-- <span th:text="${data}"></span> --><!--/* [[${data}]] */--><!--/*--> <span th:text="${data}"></span> <!--*/--> // 또는 <!--/* <span th:text="${data}"></span> */-->
- 타임리프 파서 주석은 렌더링 시 보이지 않는다.
th: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>
<script th:inline="javascript"> let username = [[${user.username}]]; let age = [[${user.age}]]; </script>
let username2 = /*[[${user.username}]]*/ "test username";let user = [[${user}]];<script th:inline="javascript"> [# th:each="user, stat : ${users}"] let user[[${stat.count}]] = [[${user}]]; [/] </script>

th:fragment를 태그에 붙여 다른 html파일에서 가져와 사용할 수 있다.
<footer th:fragment="copy">footer 자리입니다.</footer>
th:insert의 경우 태그 안에 가져온 태그를 삽입하고, th:replace의 경우 태그를 대체한다.
문법은 ~{가져올 태그가 있는 파일 경로 :: fragment이름}이다.
<h2>부분 포함 : insert</h2> <div th:insert="~{template/fragment/footer :: copy}"></div> <h2>부분 포함 : replace</h2> <div th:replace="~{template/fragment/footer :: copy}"></div> <h2>부분 포함 단순 표현식</h2> <div th:replace="template/fragment/footer :: copy"></div>
- 소스코드에서 삽입과 대체의 차이
fragment에 파라미터를 붙여 메서드처럼 가져와 사용할 수 있다.
<footer th:fragment="copyParam(param1,param2)"> <p>파라미터 자리입니다.</p> <p th:text="${param1}"> </p> <p th:text="${param2}"> </p> </footer>
<h1>파라미터 사용</h1> <div th:replace="template/fragment/footer :: copyParam('data1','data2')"></div>