Thymeleaf 정리

특징

  • 서버 사이드 HTML 렌더닝하는 용도로 사용
  • 순수한 HTML을 최대한 유지하려는 특징 => JSP와의 확연한 차이점
  • 스프링과의 통합 지원

공부하면서 자주 쓰인 기능들

  • th:field = “${kkk}”
    • html의 id, name, value 속성을 kkk로 자동 생성
  • th:object = “${object이름}”

    • model.addAttribute로 넘겨받은 객체를 사용 가능

    • th:object 하위의 태그들에서 해당 객체를 사용할 때, *{property} 식으로 생략 가능

    • ex)

      • <form action="item.html" th:action th:object="${item}" method="post">
            <div>
              <label for="itemName">상품명</label>
              <input type="text" th:field="*{itemName}" id="itemName" name="itemName" class="form-control" placeholder="이름을 입력하세요">
            </div>
        </form>
        
      • th:field=”${item.itemName}”=> th:field=”*{itemName}”
  • checkbox 편의 기능

    • 기존에 checkbox를 사용하는 경우, check 박스에 체크를 하지 않으면 false가 아닌 null이 반환됨

    • <input type="checkbox" id="open" name="open" class="form-check-input"/>
          
      2022-07-31 13:38:30.948  INFO 21560 --- [nio-8080-exec-3] y.thyme.web.form.FormItemController      : item.open=null
      
    • 위처럼 로그를 찍어보면 null이 반환되는 것을 확인할 수 있음 => 이 경우, 로직 상 문제 발생 가능

    • 이를 스프링 MVC는 아래와 같이 편법을 이용하여 방지할 수 있음

    • <input type="checkbox" id="open" name="open" th:field="${item.open}" class="form-check-input"/>
      <input type="hidden" name="_open" value="on"/> <!-- 히든 필드 추가 -->
      
    • 타임리프의 th:field 기능을 사용하면 이 부분을 간단하게 해결할 수 있음

    • <input type="checkbox" id="open" name="open" th:field="${item.open}" class="form-check-input"/>
      
    • 위처럼 th:field 기능을 사용하면, input hidden 필드를 자동으로 생성해줌

    • 또한, checked 상태를 알아서 선택해줌

      • checked가 존재하면 원래 무조건 체크 처리가 됨
      • 이를 타임리프가 알아서 체크가 있는 경우에만 checked를 생성해줌
  • th:for=”${#ids.prev(‘id명’)}”

    • label에 주로 사용되는 타임리프 기능

    • id가 동적으로 생성되는 경우, label의 for 기능을 미리 id에 맞춰서 할당할 수 없음

    • 이를 해결하기 위해 타임리프에서 #ids라는 기능을 제공

    • 동적 생성되는 id명에 인덱스 번호를 붙여 자동으로 매핑해줌

    • 예제 코드

    • <div th:each="region : ${regions}" class="form-check form-check-inline">
          <input type="checkbox" th:field="${item.regions}" th:value="${region.key}" class="form-check-input">
          <label th:for="${#ids.prev('regions')}"
                   th:text="${region.value}" class="form-check-label">서울</label>
      </div>
      
    • 코드 해석

      • 맨 바깥 div에서 th:each로 안의 태그들을 동적으로 반복하여 생성함
      • 이 경우, th:field 속성으로 인하여 input 태그의 id, name이 자동으로 생성됨
      • name은 그렇다쳐도 id는 중복을 허용하지 않기 때문에 regions1, regions2와 같이 내부적으로 인덱스 번호를 붙여 생성됨
      • label 태그에서 for 기능을 사용하려면 동적으로 생성된 input 태그의 id 값에 맞춰서 매칭시켜줘야 할 필요가 있음
      • th:for=”${#ids.}” 기능으로 id를 동적으로 생성함
      • 이때, prev를 붙여 앞 태그인 input에서 내부적으로 생성된 인덱스를 그대로 가져와 regions에 붙임
      • 결과적으로 regions1, regions2가 되므로 input 태그와 알맞게 매칭 가능
    • #ids의 prev, next 메소드

      • prev : 앞의 태그에서 사용한 인덱스 번호를 그대로 가져옴 (input이 lable보다 먼저 위치)
      • next : 뒤의 태그에서 사용한 인덱스 번호를 그대로 가져옴 (label이 input보다 먼저 위치)

인프런 - 김영한님의 Spring MVC 2편을 정리한 내용입니다.

김영한님 인프런 강의

댓글남기기