파게로그
Thymeleaf 본문
타임리프라고 부르는데 간단한 프로젝트에는 많이 쓰인다고 한다.
⛳ 공식 사이트
▪ 메인 www.thymeleaf.org
▪ Thymeleaf 문서 www.thymeleaf.org/documentation.html
▪ Thymeleaf + Spring 문서 www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html
▪ 실습 튜토리얼 itutorial.thymeleaf.org
⛳ 아래 블로그가 처음에 읽기에는 나쁘지 않았다. 템플릿 엔진의 개념과 종류, JSP보다 Thymeleaf를 권장하는 이유를 간단하게 볼 수 있다.
Thymeleaf is a modern server-side Java template engine for both web and standalone environments.
Thymeleaf's main goal is to bring elegant natural templates to your development workflow — HTML that can be correctly displayed in browsers and also work as static prototypes, allowing for stronger collaboration in development teams.
With modules for Spring Framework, a host of integrations with your favourite tools, and the ability to plug in your own functionality, Thymeleaf is ideal for modern-day HTML5 JVM web development — although there is much more it can do.
주요한 기능은 다음과 같다.
- Natural templates
- Integrations galore
Thymeleaf Standard Dialect 5분 맛보기
www.thymeleaf.org/doc/articles/standarddialect5minutes.html
🍦 1. Standard Dialects
Thymeleaf는 아주 높은 확장성을 지니며, 템플릿 속성, 그리고 태그까지도 내가 원하는 이름과 함께 내가 원하는 대로 일련의 세트를 정의할 수 있도록 하고, 내가 원하는 문법 내에서 내가 원하는 expression들을 evaluate할 수 있도록 하며, 내가 원하는 로직을 적용할 수 있도록 한다. 즉, 보다 template engine framework와 같은 것이다.
그럼에도 불구하고, 별도의 설치 및 구성 없이, 이는 Standard나 SpringStandard로 불리는 standard dialects로 가능한데 이는 기능의 집합으로서, 대부분의 시나리오에 대해서 충분하거나 넘치는 기능을 갖는다. 템플릿에 이러한 standard dialects가 쓰였을 때에는 바로 식별할 수 있는데, 이들은 <span th:text="...">와 같이 th 접두사로 시작하는 속성을 포함하기 때문이다.
Standard와 SpringStandard dialects는 거의 동일하나, 다만 SpringStandard는 표현의 evaluation을 위해 OGNL(Object-Graph Navigation Language) 대신 Spring Expression Language를 쓰는 것과 같은 Spring MVC 어플리케이션과 통합하기 위한 특정 기능을 포함하고 있다.
또한 여기서 별다른 언급이 없으면 주로 Standard dialects에 대해 언급하는 것이다.
🍦 2. Standard Expression syntax
대개의 Thymeleaf 속성은 그 값을 expression이거나, 또는 expression을 포함하는 것으로 설정하는데, 그 안에 쓰인 dialects 때문에 이를 Standard Expressions라고 부를 것이다. 이들은 아래 5가지의 유형일 수 있다.
${. . .} | Variable expressions |
*{. . .} | Selection expressions |
#{. . .} | Message(i18n) expressions |
@{. . .} | Link(URL) expressions |
~{. . .} | Fragment expressions |
2.1. Variable expressions
OGNL expression, 또는 Spring과 Thymeleaf를 통합하고 있다면 Spring EL로서 context variable 위에서 실행되며, Spring 용어로는 model attributes라 불린다. 아래와 같이 생겼다.
${session.user.name}
또한 그것들은 attribute를 이용하여, attribute 값이나 그것의 부분으로서 찾을 수 있다.
<span th:text="${book.author.name}">
위 표현은 OGNL과 SpringEL 모두에서 다음과 같다.
((Book)context.getVariable("book")).getAuthor().getName()
하지만 우리는 output만 수반할 뿐 아니라 conditionals, iteration과 같은 보다 복잡한 처리를 수반하는 시나리오에서 다양한 표현을 찾을 수 있다.
<li th:each="book : ${books}">
여기서 ${books}는 context에서 books라 불리는 변수를 선택하며, th:each 루프에서 사용될 iterable로 evaluate한다.
2.2. Selection expressions
Selection expressions는 Variable expressions와 거의 비슷한데, 다만 모든 context variables map이 아닌 이전에 선택된 객체에 대해서만 실행된다. 아래와 같이 생겼다.
*{customer.name}
그들의 행위 대상 객체는 th:object 속성에 의해서 구체화된다.
<div th:object="${book}">
<!-- ... -->
<span th:text="*{title}">...</span>
<!-- ... -->
</div>
이는 다음과 동등하다.
{
final Book selection = (Book) context.getVariable("book"); // th:object="${book}"
output(selection.getTitle()); // th:text="*{title}"
}
2.3. Message (i18n) expressions
'i18n'은 'internationalization'과 동일한 의미로서 그냥 i랑 n 사이에 18개의 문자가 있어서 저렇게 쓴다고 한다. SW의 국제화에서는 다음과 같은 작업들이 요구된다.
▪ 언어 및 지역에 따른 번역
▪ 운영체제 및 플랫폼에 따른 인코딩
▪ 문자열 치환 방법
▪ 국제화 UI (문자열 크기 변화, 폰트, 아이콘 등)
▪ 쓰기 방향의 차이 (LTR, RTL)
▪ 숫자, 공백, 화폐, 날짜, 주소, 측정 단위 등 표기
▪ 타임존, 썸머 타임 등 시각
▪ 문자열 정렬 방법
Message expressions는 종종 text externalization, internationalization or i18n이라 불리는데, 우리가 .properties 파일과 같은 외부 소스로부터 locale-specific한 메시지를 검색하도록 해주며, 이는 그들을 key를 통해 참조하며 수의적으로 일련의 파라미터를 적용하여 참조함으로써 이루어진다.
Spring applications에서는, 아래 코드는 자동적으로 Spring의 MessageSource 매커니즘과 통합할 것이다.
#{main.title}
#{message.entrycreated(${entryId})}
이들을 아래와 같은 템플릿에서 찾을 수 있다.
<table>
...
<th th:text="#{header.address.city}">...</th>
<th th:text="#{header.address.country}">...</th>
...
</table>
message key가 context 변수의 값에 의해 결정되기를 원하거나, 다음과 같이 파라미터로 변수를 특정하기를 원한다면, Message expressions 내에 Variable expressions를 사용할 수 있다.
#{${config.adminWelcomeKey}(${session.user.name})}
2.4. Link(URL) expressions
Link expressions는 URL을 빌드하고 유용한 context와 세션 정보를 더하도록(URL rewriting이라 불리는 작업) 의도되었다. 따라서 내 웹 서버의 /myapp이라는 context에 배포된 웹 어플리케이션의 경우 expression은 다음과 같다.
<a th:href="@{/order/list}">...</a>
그리고 위의 표현은 아래와 같이 변환될 수 있다.
<a href="/myapp/order/list">...</a>
만약 우리가 활성화되지 않은 세션과 쿠키를 유지해야 한다면, 또는 서버가 이를 알지 못한다면 아래와 같이 작성할 수 있다.
<a href="/myapp/order/list;jsessionid=23fa31abd41ea093">...</a>
또한 URL은 아래와 같이 파라미터를 가질 수 있다.
<a th:href="@{/order/details(id=${orderId},type=${orderType})}">...</a>
위의 표현은 아래와 같다. &는 &로 escape된 것을 볼 수 있다.
<!-- Note ampersands (&) should be HTML-escaped in tag attributes... -->
<a href="/myapp/order/details?id=23&type=online">...</a>
Link expressions는 상대적일 수 있는데, URL에 접두사로 붙는 application context가 없는 경우를 말한다.
<a th:href="@{../documents/report}">...</a>
또한 server-relative일 수 있다(다시 말하지만, 접두사로 붙는 application context가 없다).
<a th:href="@{~/contents/main}">...</a>
또한 protocol-relative일 수 있다(절대경로 URL처럼, 그러나 브라우저는 표시되는 페이지에서 같은 HTTP나 HTTPS 프로토콜을 사용할 것이다).
<a th:href="@{//static.mycompany.com/res/initial}">...</a>
물론 다음과 같이 Link expressions는 절대경로일 수 있다.
<a th:href="@{http://www.mycompany.com/main}">...</a>
하지만 protocol-relative하거나 절대경로 URL에서는, Thymeleaf Link Expression은 어떤 값을 더하나? 쉽다. response filters에 의해 정의된 URL-rewriting의 가능성이다. Servlet 기반의 웹 어플리케이션에서는, context-relative, relative, absolute 등 모든 결과 URL에 대해서 Thymeleaf는 항상 HttpServletResponse.encodeUrl(...) 메커니즘을 호출할 것이고 그 후에 URL을 표시할 것이다. 즉 필터는 어플리케이션을 위한 커스터마이즈된 URL-rewriting을 수행할 수 있다는 것이며, 이는 HttpServletResponse 객체를 wrapping하는 보편적인 매커니즘 덕분이다.
2.5. Fragment expressions
Fragment expressions는 markup의 파편을 표현하고 그것들을 템플릿 주변으로 옮기는 데에 쉬운 방법이다. 이러한 표현 덕분에 파편은 복제될 수 있고, 다른 템플릿에 arguments로 전달될 수 있다.
가장 일반적인 사용법은 th:insert나 th:replace를 이용한 fragment insertion이다.
<div th:insert="~{commons :: main}">...</div>
하지만 이는 아래와 같이, 다른 변수와 함께 어디에나 사용될 수 있다.
<div th:with="frag=~{footer :: #main/text()}">
<p th:insert="${frag}">
</div>
fragment expressions는 arguments를 가질 수 있다.
2.6. Literals and operations
리터럴과 연산자가 잘 구비되어 있다.
- Literals:
- Text literals: 'one text', 'Another one!',…
- Number literals: 0, 34, 3.0, 12.3,…
- Boolean literals: true, false
- Null literal: null
- Literal tokens: one, sometext, main,…
- Text operations:
- String concatenation: +
- Literal substitutions: |The name is ${name}|
- Arithmetic operations:
- Binary operators: +, -, *, /, %
- Minus sign (unary operator): -
- Boolean operations:
- Binary operators: and, or
- Boolean negation (unary operator): !, not
- Comparisons and equality:
- Comparators: >, <, >=, <= (gt, lt, ge, le)
- Equality operators: ==, != (eq, ne)
- Conditional operators:
- If-then: (if) ? (then)
- If-then-else: (if) ? (then) : (else)
- Default: (value) ?: (defaultvalue)
2.7. Expression preprocessing
expression에 대해 알아야 할 마지막 것은, expression preprocessing이라는 것인데, 이는 다음과 같이 __ 사이에 있는 것으로 구분된다.
#{selection.__${sel.code}__}
처음 실행될 variable expression(${sel.code})이 보이며, 이는 아마 "ALL"이 결과인데, 이는 후에 실행될 real expression의 부분으로 사용될 것이며, 이 경우에는 internationalization one(selection.ALL이라는 키와 있는 메시지를 찾을)이다.
🍦 3. Some basic attributes
Standard Dialect에서 가장 기본적인 속성 중 2개를 살펴보자. th:text로 시작하며, 태그의 body를 대체한다(notice again the prototyping abilities here).
<p th:text="#{msg.welcome}">Welcome everyone!</p>
표현에 의해 리턴된 배열이나 리스트에 의해 명시된 횟수만큼 element를 반복하는 th:each는, element 반복을 위한 내부 변수를 만드는데, Java의 foreach 표현과 문법적으로 동일하다.
<li th:each="book : ${books}" th:text="${book.title}">En las Orillas del Sar</li>
마지막으로, Thymeleaf는 단지 자신의 expression을 evaluate하고 속성들의 값을 결과값으로 설정하는 특정 XHTML이나 HTML5 속성을 위한 많은 th 속성을 포함한다. 그들의 이름은 그들이 설정할 값의 속성을 모방한다.
<form th:action="@{/createOrder}">
<input type="button" th:value="#{form.submit}" />
<a th:href="@{/admin/users}">
🍦 4. Want to know more?
"Using Thymeleaf" 튜토리얼을 추천한다.
'콤퓨타 왕기초 > Spring Boot' 카테고리의 다른 글
[Persistence Framework] Model(DAO, DTO, Service) (0) | 2021.05.07 |
---|---|
[Persistence Framework] JPA vs MyBatis (0) | 2021.05.07 |
Controller의 객체명 설정 (0) | 2021.05.04 |
DevTools, Thymeleaf, View Resolver (0) | 2021.05.04 |
Why Spring Boot? (0) | 2021.05.04 |