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>