<body>
<h1>text vs utext</h1>
<ul>
<li>th:text = <span th:text="${data}"></span></li>
<li>th:utext = <span th:utext="${data}"></span></li>
</ul>
<h1><span th:inline="none">[[...]] vs [(...)]</span></h1>
<ul>
<li><span th:inline="none">[[...]] = </span>[[${data}]]</li>
<li><span th:inline="none">[(...)] = </span>[(${data})]</li>
</ul>
</body>
String escapedText = HtmlUtils.htmlEscape("<script>alert('XSS');</script>");
// escapedText = "<script>alert('XSS');</script>"
String unescapedText = HtmlUtils.htmlUnescape("<b>Hello</b>");
// unescapedText = "<b>Hello</b>"
λ³μ ννμ : '${...}'
- μ΄ λ³μ ννμμλ SpringEL μ΄λΌλ μ€νλ§μ΄ μ 곡νλ ννμμ μ¬μ©ν μ μλ€.
<body>
<h1>SpringEL ννμ</h1>
<ul>Object
<li>${user.username} = <span th:text="${user.username}"></span></li>
<li>${user['username']} = <span th:text="${user['username']}"></span></li>
<li>${user.getUsername()} = <span th:text="${user.getUsername()}"></span></li>
</ul>
<ul>List
<li>${users[0].username} = <span th:text="${users[0].username}"></span></li>
<li>${users[0]['username']} = <span th:text="${users[0]['username']}"></span></li>
<li>${users[0].getUsername()} = <span th:text="${users[0].getUsername()}"></span></li>
</ul>
<ul>Map
<li>${userMap['userA'].username} = <span th:text="${userMap['userA'].username}"></span></li>
<li>${userMap['userA']['username']} = <span th:text="${userMap['userA']['username']}"></span></li>
<li>${userMap['userA'].getUsername()} = <span th:text="${userMap['userA'].getUsername()}"></span></li>
</ul>
</body>
<h1>μ§μ λ³μ - (th:with)</h1>
<div th:with="first=${users[0]}">
<p>μ²μ μ¬λμ μ΄λ¦μ <span th:text="${first.username}"></span></p>
</div>
κΈ°μ‘΄μλ ${#request}, ${#response}, ${#session}, ${#servletContext} λ₯Ό μ§μ νμμ§λ§ μ€νλ§ λΆνΈ 3.0 μ΄ν λΆν°λ μ§μνμ§ μλλ€.
λ°λΌμ modelμ μ§μ λ΄μμ μ¬μ©ν΄μΌνλ€.
@GetMapping("/basic-objects")
public String basicObjects(Model model, HttpServletRequest request,
HttpServletResponse response, HttpSession session) {
session.setAttribute("sessionData", "Hello Session");
model.addAttribute("request", request);
model.addAttribute("response", response);
model.addAttribute("servletContext", request.getServletContext());
return "basic/basic-objects";
}
μ νΈλ¦¬ν° κ°μ²΄λ₯Ό μμλκ³ , λμ€μ νμν λ λ©λ΄μΌμ μ°Ύμμ μ¬μ©νλ©΄ λλ€.
<body>
<h1>LocalDateTime</h1>
<ul>
<li>default = <span th:text="${localDateTime}"></span></li>
<li>yyyy-MM-dd HH:mm:ss = <span th:text="${#temporals.format(localDateTime, 'yyyy-MM-dd HH:mm:ss')}"></span></li>
</ul>
<h1>LocalDateTime - Utils</h1>
<ul>
<li>${#temporals.day(localDateTime)} = <span th:text="${#temporals.day(localDateTime)}"></span></li>
<li>${#temporals.month(localDateTime)} = <span th:text="${#temporals.month(localDateTime)}"></span></li>
<li>${#temporals.monthName(localDateTime)} = <span th:text="${#temporals.monthName(localDateTime)}"></span></li>
<li>${#temporals.monthNameShort(localDateTime)} = <span th:text="${#temporals.monthNameShort(localDateTime)}"></span></li>
<li>${#temporals.year(localDateTime)} = <span th:text="${#temporals.year(localDateTime)}"></span></li>
<li>${#temporals.dayOfWeek(localDateTime)} = <span th:text="${#temporals.dayOfWeek(localDateTime)}"></span></li>
<li>${#temporals.dayOfWeekName(localDateTime)} = <span th:text="${#temporals.dayOfWeekName(localDateTime)}"></span></li>
<li>${#temporals.dayOfWeekNameShort(localDateTime)} = <span th:text="${#temporals.dayOfWeekNameShort(localDateTime)}"></span></li>
<li>${#temporals.hour(localDateTime)} = <span th:text="${#temporals.hour(localDateTime)}"></span></li>
<li>${#temporals.minute(localDateTime)} = <span th:text="${#temporals.minute(localDateTime)}"></span></li>
<li>${#temporals.second(localDateTime)} = <span th:text="${#temporals.second(localDateTime)}"></span></li>
<li>${#temporals.nanosecond(localDateTime)} = <span th:text="${#temporals.nanosecond(localDateTime)}"></span></li>
</ul>
</body>
νμ 리νμμ URLμ μμ±ν λλ '@{...}' λ¬Έλ²μ μ¬μ©νλ©΄ λλ€.
리ν°λ΄μ μμ€ μ½λμμ κ³ μ λ κ°μ λ§νλ μ©μ΄μ΄λ€.
<body>
<h1>리ν°λ΄</h1>
<ul>
<!--μ£Όμ! λ€μ μ£Όμμ νλ©΄ μμΈκ° λ°μν¨-->
<!-- <li>"hello world!" = <span th:text="hello world!"></span></li>-->
<li>'hello' + ' world!' = <span th:text="'hello' + ' world!'"></span></li>
<li>'hello world!' = <span th:text="'hello world!'"></span></li>
<li>'hello ' + ${data} = <span th:text="'hello ' + ${data}"></span></li>
<li>리ν°λ΄ λ체 |hello ${data}| = <span th:text="|hello ${data}|"></span></li>
</ul>
</body>
νμ리ν μ°μ°μ μλ°μ ν¬κ² λ€λ₯΄μ§ μλ€.
HTMLμμμ μ¬μ©νκΈ° λλ¬Έμ HTML μν°ν°λ₯Ό μ¬μ©νλ λΆλΆλ§ μ£Όμ νλ©΄ λλ€.
<body>
<ul>
<li>μ°μ μ°μ°
<ul>
<li>10 + 2 = <span th:text="10 + 2"></span></li>
<li>10 % 2 == 0 = <span th:text="10 % 2 == 0"></span></li>
</ul>
</li>
<li>λΉκ΅ μ°μ°
<ul>
<li>1 > 10 = <span th:text="${1 > 10}"></span></li>
<li>1 gt 10 = <span th:text="${1 gt 10}"></span></li>
<li>1 >= 10 = <span th:text="${1 >= 10}"></span></li>
<li>1 ge 10 = <span th:text="${1 ge 10}"></span></li>
<li>1 == 10 = <span th:text="${1 == 10}"></span></li>
<li>1 != 10 = <span th:text="${1 != 10}"></span></li>
</ul>
</li>
<li>쑰건μ
<ul>
<li>(10 % 2 == 0)? 'μ§μ':'νμ' = <span th:text="(10 % 2 == 0)? 'μ§μ':'νμ'"></span></li>
</ul>
</li>
<li>Elvis μ°μ°μ
<ul>
<li>${data}?: 'λ°μ΄ν°κ° μμ΅λλ€.' = <span th:text="${data}?: 'λ°μ΄ν°κ° μμ΅λλ€.'"></span></li>
<li>${nullData}?: 'λ°μ΄ν°κ° μμ΅λλ€.' = <span th:text="${nullData}?: 'λ°μ΄ν°κ° μμ΅λλ€.'"></span></li>
</ul>
</li>
<li>No-Operation
<ul>
<li>${data}?: _ = <span th:text="${data}?: _">λ°μ΄ν°κ° μμ΅λλ€.</span></li>
<li>${nullData}?: _ = <span th:text="${nullData}?: _">λ°μ΄ν°κ° μμ΅λλ€.</span></li>
</ul>
</li>
</ul>
</body>
νμ리νλ μ£Όλ‘ HTML νκ·Έμ 'th:*' μμ±μ μ§μ νλ λ°©μμΌλ‘ λμνλ€.
'th:*'λ‘ μμ±μ μ§μ νλ©΄ κΈ°μ‘΄ μμ±μ λ체νλ€.
κΈ°μ‘΄ μμ±μ΄ μμΌλ©΄ μλ‘ λ§λ λ€.
<body>
<h1>μμ± μ€μ </h1>
<input type="text" name="mock" th:name="userA" />
<h1>μμ± μΆκ°</h1>
- th:attrappend = <input type="text" class="text" th:attrappend="class=' large'" /><br/>
- th:attrprepend = <input type="text" class="text" th:attrprepend="class='large '" /><br/>
- th:classappend = <input type="text" class="text" th:classappend="large" /><br/>
<h1>checked μ²λ¦¬</h1>
- checked o <input type="checkbox" name="active" th:checked="true" /><br/>
- checked x <input type="checkbox" name="active" th:checked="false" /><br/>
- checked=false <input type="checkbox" name="active" checked="false" /><br/>
</body>
νμ리νμμ λ°λ³΅μ 'th:each'λ₯Ό μ¬μ©νλ€. μΆκ°λ‘ λ°λ³΅ν΄μ μ¬μ©ν μ μλ μ¬λ¬ μν κ°μ μ§μνλ€.
<tr th:each="user : ${users}">
<tr th:each="user, userStat : ${users}">
<body>
<h1>κΈ°λ³Έ ν
μ΄λΈ</h1>
<table border="1">
<tr>
<th>username</th>
<th>age</th>
</tr>
<tr th:each="user : ${users}">
<td th:text="${user.username}">username</td>
<td th:text="${user.age}">0</td>
</tr>
</table>
<h1>λ°λ³΅ μν μ μ§</h1>
<table border="1">
<tr>
<th>count</th>
<th>username</th>
<th>age</th>
<th>etc</th>
</tr>
<tr th:each="user : ${users}">
<td th:text="${userStat.count}">username</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>
current = <span th:text="${userStat.current}"></span>
</td>
</tr>
</table>
</body>
νμ리νμ 쑰건μ if, unless(ifμ λ°λ)
<span th:text="'λ―Έμ±λ
μ'" th:if="${user.age lt 20}"></span>
<body>
<h1>if, unless</h1>
<table border="1">
<tr>
<th>count</th>
<th>username</th>
<th>age</th>
</tr>
<tr th:each="user, userStat : ${users}">
<td th:text="${userStat.count}">1</td>
<td th:text="${user.username}">username</td>
<td>
<span th:text="${user.age}">0</span>
<span th:text="'λ―Έμ±λ
μ'" th:if="${user.age lt 20}"></span>
<span th:text="'λ―Έμ±λ
μ'" th:unless="${user.age ge 20}"></span>
</td>
</tr>
</table>
<h1>switch</h1>
<table border="1">
<tr>
<th>count</th>
<th>username</th>
<th>age</th>
</tr>
<tr th:each="user, userStat : ${users}">
<td th:text="${userStat.count}">1</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>
</table>
</body>
<!--
<span th:text="${data}">html data</span>
-->
<!--/* [[${data}]] */-->
<!--/*-->
<span th:text="${data}">html data</span>
<!--*/-->
<!--/*/
<span th:text="${data}">html data</span>
/*/-->
'th:block'μ HTML νκ·Έκ° μλ νμ리νμ μ μΌν μ체 νκ·Έμ΄λ€.
<body>
<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>
</body>
νμ리νλ μλ°μ€ν¬λ¦½νΈμμ νμ리νλ₯Ό νΈλ¦¬νκ² μ¬μ©ν μ μλ μλ°μ€ν¬λ¦½νΈ μΈλΌμΈ κΈ°λ₯μ μ 곡νλ€.
μλ°μ€ν¬λ¦½νΈ μΈλΌμΈ κΈ°λ₯μ λ€μκ³Ό κ°μ΄ μ μ©νλ©΄λλ€.
<script th:inline="javascript">
<!-- μλ°μ€ν¬λ¦½νΈ μΈλΌμΈ each -->
<script th:inline="javascript">
[# th:each="user, stat : ${users}"]
var user[[${stat.count}]] = [[${user}]];
[/]
</script>
<!-- μλ°μ€ν¬λ¦½νΈ μΈλΌμΈ μ¬μ© μ -->
<script>
var username = [[${user.username}]];
var age = [[${user.age}]];
//μλ°μ€ν¬λ¦½νΈ λ΄μΆλ΄ ν
νλ¦Ώ
var username2 = /*[[${user.username}]]*/ "test username";
//κ°μ²΄
var user = [[${user}]];
</script>
<!-- μλ°μ€ν¬λ¦½νΈ μΈλΌμΈ μ¬μ© ν -->
<script th:inline="javascript">
var username = [[${user.username}]];
var age = [[${user.age}]];
//μλ°μ€ν¬λ¦½νΈ λ΄μΆλ΄ ν
νλ¦Ώ
var username2 = /*[[${user.username}]]*/ "test username";
//κ°μ²΄
var user = [[${user}]];
</script>
<!-- μλ°μ€ν¬λ¦½νΈ μΈλΌμΈ each -->
<script th:inline="javascript">
[# th:each="user, stat : ${users}"]
var user[[${stat.count}]] = [[${user}]];
[/]
</script>
νμ리νλ ν νλ¦Ώ μ‘°κ°κ³Ό λ μ΄μμ κΈ°λ₯μ μ 곡νλ€.
<div th:insert="~{template/fragment/footer :: copy}"></div>
<div th:replace="~{template/fragment/footer :: copy}"></div>
<div th:replace="template/fragment/footer :: copy"></div>
<div th:replace="~{template/fragment/footer :: copyParam ('λ°μ΄ν°1', 'λ°μ΄ν°2')}"></div>
<body>
<footer th:fragment="copy">
νΈν° μ리 μ
λλ€.
</footer>
<footer th:fragment="copyParam (param1, param2)">
<p>νλΌλ―Έν° μ리 μ
λλ€.</p>
<p th:text="${param1}"></p>
<p th:text="${param2}"></p>
</footer>
</body>
<body>
<h1>λΆλΆ ν¬ν¨</h1>
<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>
<h1>νλΌλ―Έν° μ¬μ©</h1>
<div th:replace="~{template/fragment/footer :: copyParam ('λ°μ΄ν°1', 'λ°μ΄ν°2')}"></div>
</body>
μ½λ μ‘°κ°μ λ μ΄μμμ λ겨μ μ¬μ©νλ λ°©λ²μ΄λ€.
μλ₯Ό λ€μ΄ <header>μ 곡ν΅μΌλ‘ μ¬μ©νλ css, javascript κ°μ μ 보λ€μ΄ μλλ°, μ΄λ¬ν κ³΅ν΅ μ 보λ€μ ν κ³³μ λͺ¨μλκ³ , 곡ν΅μΌλ‘ μ¬μ©νμ§λ§, κ° νμ΄μ§λ§λ€ νμν μ 보λ₯Ό λ μΆκ°ν΄μ μ¬μ©νκ³ μΆλ€λ©΄ λ€μκ³Ό κ°μ΄ μ¬μ©νλ©΄ λλ€.
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="common_header(title,links)">
<title th:replace="${title}">λ μ΄μμ νμ΄ν</title>
<!-- κ³΅ν΅ -->
<link rel="stylesheet" type="text/css" media="all" th:href="@{/css/awesomeapp.css}">
<link rel="shortcut icon" th:href="@{/images/favicon.ico}">
<script type="text/javascript" th:src="@{/sh/scripts/codebase.js}"></script>
<!-- μΆκ° -->
<th:block th:replace="${links}" />
</head>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="template/layout/base :: common_header(~{::title},~{::link})">
<title>λ©μΈ νμ΄ν</title>
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
<link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}">
</head>
<body>
λ©μΈ 컨ν
μΈ
</body>
</html>
ν νλ λ μ΄μμμ <header>μ λμλ§ μ μ©νλκ² μλλΌ <html>μ 체μ μ μ©ν μλ μλ€.
<!DOCTYPE html>
<html th:fragment="layout (title, content)" xmlns:th="http://www.thymeleaf.org">
<head>
<title th:replace="${title}">λ μ΄μμ νμ΄ν</title>
</head>
<body>
<h1>λ μ΄μμ H1</h1>
<div th:replace="${content}">
<p>λ μ΄μμ 컨ν
μΈ </p>
</div>
<footer>
λ μ΄μμ νΈν°
</footer>
</body>
</html>
<!DOCTYPE html>
<html th:replace="~{template/layoutExtend/layoutFile :: layout(~{::title}, ~{::section})}"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>λ©μΈ νμ΄μ§ νμ΄ν</title>
</head>
<body>
<section>
<p>λ©μΈ νμ΄μ§ 컨ν
μΈ </p>
<div>λ©μΈ νμ΄μ§ ν¬ν¨ λ΄μ©</div>
</section>
</body>
</html>