본문 바로가기

카테고리 없음

Thymeleaf 정리

Thymeleaf란?

  • JSP를 대신하는 목적으로 작성된 라이브러리이고 템플릿 엔진이다.
  • 템플릿 이기에 JSP 처럼 직접 데이터를 생성하지 않고 만들어진 결과에 데이터를 맞춰서 보여준다.
  • 서버에서 동작하기는 하지만 HTML을 기반으로 화면을 구성하기 때문에 조금 더 HTML에 가까운 방식으로 작성된다.

사용 방법

HTML 파일 상단 네임스페이스에 <html xml:th="http://www.thymeleaf.org"> 태그를 추가한다.

th 태그를 사용해서 Model에 담긴 데이터를 사용할 때는 ‘해당 변수를 찾을 수 없다’ 라는 에러가 날 수 있다. (인텔리제이 버전에 따라 다름)
만일 에러가 발생하는 경우에는 인텔리제이의 설정을 변경해야하는데 다음과 같이 진행하면 된다. Setting → Thymeleaf 검색 → Unresolved references.. 체크 해제 → 이후 에디터(html 파일) 종료 후 실행
-> 변수에 대한 검사를 하지 않는 설정이다.

Thymeleaf 기초 문법

더보기
1. Model의 데이터 출력 방법
th 태그 방식, EL이랑 비슷하나 th 태그 포함
<h4 th:text=”${name}”/>

inLine 방식
[[${name}]]

2. 주석 처리
<!--/*  ...   */-->
 → 브라우저에 해당 부분이 아예 표시되지 않는다.
 → Thymeleaf가 파싱 처리할 때 삭제되어 처리됨, 잘못된 문법에 대한 체크를 건너뛸 수 있음

3. 임시변수 선언
<div th:with="num1 = ${10}, num2 = ${20}">
	<h4 th:text="${num1 + num2}"/>
</div>

반복문과 제어문 처리

반복문

  • 반복이 필요한 태그에: th:each
  • 별도 태그: th:block
더보기
<!-- th:each 방식 -->
<ul>
<li th:each="str: ${list}" th:text="{str}"/>
</ul>

<!-- <th:block> -->
<ul>
	<th:block th:each="str: ${list}">
	<li> [[${str}]] </li>
	</th:block>
</ul>
  • 반복문의 status 변수
  •   → index/count/size/first/last/add/even
더보기
<ul>
	<li th:each="str, status: ${list}">
		[[${status.index}]] -- [[${str}]]
	</li>
</ul>

<!-- index: 0, count: 1 -->

제어문

  • th:if / th:unless / th:switch / 삼항연산자
더보기
<!-- th:if, th:unless -->
<ul>
	<li th:each="str, status: ${list}">
		<span th:if="${status.odd}"> ODD -- [[${str}]] </span>
		<span th:unless="${status.odd"> EVEN -- [[${str}]] </span>
	</li>
</ul>

<!-- 홀수번째만 -->
<ul>
    <li th:each="str, status: ${list}">
        <span th:text="${status.odd} ? 'ODD ---'+${str}"></span>
    </li>
</ul>

<!-- 삼항 연산자 -->
<ul>
    <li th:each="str, status: ${list}">
        <span th:text="${status.odd} ? 'ODD ---'+${str} : 'EVEN ---'+${str}"></span>
    </li>
</ul>

<!-- switch 문 -->
<ul>
    <li th:each="str, status: ${list}">
        <th:block th:switch="${status.index % 3}">
            <span th:case="0">0</span>
            <span th:case="1">1</span>
            <span th:case="2">2</span>
        </th:block>
    </li>
</ul>

 

thymeleaf 링크 처리

  • JSP와 달리 특정 프로젝트의 경로부터 시작하는 것을 고려하지 않아도 된다.
  • ‘key=value’ 의 형태의 파라미터는 ‘()’를 이용한다.
  • 쿼리 스트링에서 한글, 공백 문자 등에 대한 URL 인코딩 처리가 자동으로 이뤄진다.
  • 배열과 같이 여러개 일 경우 자동으로 같은 이름의 파라미터를 처리함 (에디터는 오류로 출력하나 정상 동작)
더보기
<!-- @로 처리함 -->
<a th:href="@{/hello}">Go to /hello</a>

<!-- key=value 형태로 파라미터 처리 ( 쿼리 스트링 ) -->
<a th:href="@{/hello(name='AAA', age= 16)}">Go to /hello</a>

<!-- 링크의 쿼리 스트링 처리, URL 인코딩 자동 처리 -->
<a th:href="@{/hello(name='한글 처리', age= 16)}">Go to /hello</a>

<!-- 배열과 같이 여러 개 파라미터 처리 -->
<a th:href="@{/hello(types=${ {'AA', 'BB', 'CC'} }, age=16)}">Go to /hello</a>
인라인 요소를 자바스크립트 내에서 활용하는법
-> var conPath = /*[[ @{/} ]]*/;

: 실제는 @{/} 요걸로 호출된다. 저 앞뒤로 붙은 /[[ ]]/ 안에 있는 Thymeleaf 문법은 스크립트 영역 안에서도 호출이 유지되게 해준다. 그리고 스크립트나 정적 리소스 패스는 타임리프 태그 th 붙이고 @{} 안에 표현 하면 된다.
ex) script th:src="@{/js/jquery-3.5.1.min.js}"

그리고 물론 th 태그 사용은 페이지 상단에 " <html xmlns:th="http://www.thymeleaf.org"> "
이렇게 정의해줘야 된다.

Thymeleaf의 특별한 기능들

타임리프의 고유기능들은 JSTL과 유사하지만 JSP보다 더욱 발전되었다.

인라인 처리

인라인 기능은 동일한 데이터를 상황에 따라 다르게 출력해 주는 기능이다. 자바스크립트를 사용할 때 편리하다.

HTML 코드나 자바스크립트에 인라인 처리를 하면 객체들을 사용할 수 있다.

자바스크립트에서 인라인 기능을 사용하려면 <script th:inline=’javascript’> 키워드를 지정해야 한다. 해당 코드를 브라우저에서 확인하면 원래의 문법으로 변환되어 있다.

더보기
<!-- 컨트롤러 -->
class SampleDTO {
        private String p1, p2, p3;

        public String getP1() {
            return p1;
        }

        public void setP1(String p1) {
            this.p1 = p1;
        }

        public String getP2() {
            return p2;
        }
    }

    @GetMapping("/ex/ex2")
    public void ex2(Model model) {
        log.info("ex/ex2.........");

        List<String> strList = IntStream.range(1, 10)
                .mapToObj(i -> "Data" + i)
                .collect(Collectors.toList());

        model.addAttribute("list", strList);

        Map<String, String> map = new HashMap<>();
        map.put("A", "AAAA");
        map.put("B", "BBBB");

        model.addAttribute("map", map);

        SampleDTO sampleDTO = new SampleDTO();
        sampleDTO.p1 = "Value -- p1";
        sampleDTO.p2 = "Value -- p2";
        sampleDTO.p3 = "Value -- p3";

        model.addAttribute("dto", sampleDTO);
    }

<!-- view -->
<div th:text="${list}"></div>
<div th:text="${map}"></div>
<div th:text="${dto}"></div>

<script th:inline="javascript">
    const list = [[${list}]]
    const map = [[${map}]]
    const dto = [[${dto}]]

    console.log(list)
    console.log(map)
    console.log(dto)
</script>

레이아웃 구성

th:block 태그를 활용해 레이아웃을 작성하고 특정한 페이지에서는 필요한 부분만을 작성하는 방식으로 개발할 수 있다. 해당 작업을 위해선 별도의 라이브러리를 추가해야 한다.

더보기
// kotlin gradle 기준입니다.
implementation("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:3.1.0")

// groovy gradle 
implementation group: 'nz.net.ultraq.thymeleaf', name: 'thymeleaf-layout-dialect', version: '3.1.0'
  • <html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout> 추가
  • layout:fragment 속성을 사용하면 다른 파일에서 해당 부분만 개발 가능
  • 아래 코드를 사용해 새로운 화면 작성 시 해당 코드를 그대로 활용하여 원하는 영역만 작성 가능 (content/script)
  • 코드
더보기
<!-- layout1.html -->
<!DOCTYPE html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Layout page</title>
</head>
<body>
<div>
  <h3>Sample Layout Header</h3>
</div>

<div layout:fragment="content">
  <p>Page content goes here</p>
</div>

<div>
  <h3>Sample Layout Footer</h3>
</div>

<th:block layout:fragment="script">

</th:block>

</body>
</html>

위의 코드로 구현된 fragment 단에 다음과 같이 추가하여 사용할 수 있음

더보기
<!-- 
~{...}는 Thymeleaf의 표현식 문법으로, 리소스 경로를 해석하는데 사용됩니다. 
여기서는 "layout/layout1.html"이라는 경로의 레이아웃 템플릿을 사용하겠다는 의미입니다.
-->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layout/layout1.html}">
<div layout:fragment="content">
    <h1>ex3.html</h1>
</div>

<script layout:fragment="script" th:inline="javascript">
    const arr = [[${arr}]]
</script>
</html>

출력 결과

이외에도 여러 빌트인 객체와 기능들이 존재함