타임리프 thymeleaf 정리 (1)

zwon·2023년 8월 31일
0

Spring

목록 보기
9/12

타임리프는 백엔드에서 HTML을 동적으로 렌더링하는 용도로 사용된다.
서버사이드렌더링(SSR)할 때 사용된다.

타임리프의 가장 큰 특징은 내츄럴 템플릿이라는 것이다.
내츄럴 템플릿이란 순수 HTML을 유지한다는 것인데 유지하기때문에 웹 브라우저에서 타임리프로 작성한 html 파일을 열어서 내용을 확인할 수 있지만 동적으로 변경된 결과는 아닐지라도 HTML 구조와 같은 부분은 볼 수 있다는 뜻이다.
그리고 서버와 뷰 템플릿을 통해 타임리프 파일이 열리면 동적으로 변경된 결과를 확인할 수 있다.

타임리프를 사용할 때는 다음과 같은 선언을 해야한다.

<html xmlns:th="http://www.thymeleaf.org">

텍스트 출력

타임리프에서 텍스트를 출력하고 싶을 때는 다음과 같이 th:text를 사용하면된다.

  • 컨트롤러 코드
@GetMapping("/text-basic")
  public String textBasic(Model model){
    model.addAttribute("data", "Hello Spring!");
    return "basic/text-basic";
  }
  • 타임리프 html 일부
<span th:text="${data}"></span>

뷰 템플릿을 통해 화면에 출력될 때는 다음과 같이 렌더링이 된다.

<span>Hello Spring!</span>

만약 태그안에 작성하지 않고 컨텐츠 부분에 바로 작성하고 싶으면 다음과 같이 작성하면된다.

<span>[[${data}]]</span>

이러면 위 결과와 동일하게 나온다.

참고로 타임리프는 [[ ]]와 같은 특수문자를 HTTP 엔티티로 이스케이프를 해준다.
만약 이스케이프 기능을 사용하고 싶지 않으면 th:utext를 사용하면된다.

  • 컨트롤러 코드
@GetMapping("/text-unescaped")
  public String upescapedBasic(Model model){
    model.addAttribute("data", "Hello <b>Spring!</b>");
    return "basic/text-unescaped";
  }
  • 타임리프 html 코드
<span th:utext="${data}"></span>

렌더링 결과 Spring!은 굵은 글자로 표현.

<span>Hello <b>Spring!</b></span>

만약 th:text였으면 아래와 같이 표현되었을 것이다.

<span>Hello &lt;b&gt;Spring!&lt;/b&gt;</b></span>

만약 콘텐츠 영역에 바로 작성하고싶으면 다음과 같이 작성하면된다.
th:text가 [[]]였다면 th:utext는[()]로 사용한다.

<span>[(${data})]</span>

스프링 변수 SpringEL

타임리프에서 변수를 사용하고 싶으면 다음과 같은 변수 표현식을 사용하면 된다.

${...}
  • 컨트롤러 코드
@GetMapping("/text-basic")
  public String textBasic(Model model){
    model.addAttribute("data", "Hello Spring!");
    return "basic/text-basic";
  }
  • 타임리프 html 코드
<span th:text="${data}"></span>

data = Hello Spring!이 담겨있는 것이고, 변수인 data를 가져오고싶으면 &{data}로 가져올 수 있다.

만약 user객체가 있고 username이라는 프로퍼티가 있다고 가정하자.
다음과 같이 Object, list, Map타입이 들어가있을때는 어떻게 값을 꺼내는지 알아보자.

@GetMapping("/variable")
  public String variable(Model model){
    User userA = new User("UserA", 10);
    User userB = new User("UserB", 20);

    ArrayList<User> list = new ArrayList<>();
    list.add(userA);
    list.add(userB);

    Map<String, User> map = new HashMap<>();
    map.put("UserA", userA);
    map.put("UserB", userB);

    model.addAttribute("user", userA);
    model.addAttribute("users", list);
    model.addAttribute("userMap", map);

    return "basic/variable";
  }

Object

<span th:text="${user.username}"></span>
<span th:text="${user['username']}"></span>

list

<span th:text="${users[0].username}"></span>
<span th:text="${users[0]['username']}"></span>
<span th:text="${users[0].getUsername()}"></span>

Map

<span th:text="${userMap['userA'].username}"></span>
<span th:text="${userMap['userA']['username']}"></span>
<span th:text="${userMap['userA'].getUsername()}"></span>

지역변수 같은 경우는 th:with를 사용할 수 있다.

<div th:with="first=${users[0]}">
  <span th:text="${first.username}"></span>
</div>

기본 객체

타임리프는 다음과 같은 객체들을 기본으로 제공해준다

  • ${#request}
  • ${#response}
  • ${#session}
  • ${#servletContext}
  • ${#locale}
<span th:text="${#request}"></span>
<span th:text="${#response}"></span>
<span th:text="${#session}"></span><
<span th:text="${#servletContext}"></span>
<span th:text="${#locale}"></span>

Bean으로 등록된 객체에 접근할 수도 있다.

  @Component("helloBean")
  static class HelloBean {
    public String hello(String data){
      return "Hello " + data;
    }
  }
<span th:text="${@helloBean.hello('Spring')}"></span>

타임리프는 자주 사용하는 것들에 대해서는 편의 객체를 제공해주는데 대표적으로 request parameter와 session이 있다.

request parameter

<span th:text="${param.paramData}"></span>

session

  • session.setAttribute("sessionData", "Hello Session!");과 같이 작성했다고 가정하면 다음과 같이 값을 편리하게 가져올 수 있다.
<span th:text="${session.sessionData}"></span>

URL 링크

타임리프에서 URL을 생성할 때에는 $표시가 아닌 @를 사용해야한다

@{...}

다음과 같이 모델에 데이터를 넘긴다고 가정하자.

model.addAttribute("param1", "data1");
model.addAttribute("param2", "data2");

링크 예시

<a th:href="@{/hello}"></a>
<a th:href="@{/hello(param1=${param1}, parma2=${param2})}"></a>
<a th:href="@{/hello/{param1}/{param2}(param1=${param1}, param2=${param2})}"></a>
<a th:href="@{/hello/{param1}(param1=${param1}, param2=${param2})}"></a>

실행 결과 다음과 같은 링크가 생성된다. (순서대로)

/hello
/hello?param1=data1&parma2=data2 -> query parameter 방식
/hello/data1/data2 -> Path variable 방식
/hello/data1?param2=data2 -> query parameter + Path variable

profile
Backend 관련 지식을 정리하는 Back과사전

0개의 댓글