6장 템플릿 엔진 알아보기

Peter·2023년 5월 13일
2
post-thumbnail

6-1-1 템플릿 엔진이란?

뷰는 사용자에게 보여줄 내용을 처리 결과 데이터를 가지고 HTML을 생성해서 클라이언트에 응답을 돌려주는 역할을 한다. 템플릿 엔진은 프로그래밍 언어별로 많지만 간단하게 설명하면 '데이터를 미리 정의된 템플릿에 바인딩해서 뷰의 표시르 도와주는 것'이다.

6-1-2 타임리프란?

타임리프의 특징 두 가지
1. HTML 기반의 템플릿 엔진으로, 정해진 문법으로 작성하면 페이지를 동적으로 조립해 준다(조건 분기나 반복 구문 등을 사용할 수 있다).
2. HTML을 기반으로 하기 때문에 최종 출력을 생각하면서 뷰를 만들 수 있다. 즉, 타임리프를 사용하면 디자이너와 쉽게 분업할 수 있다.

6-2-1 Model 인터페이스란?

Model 인터페이스의 특징 세 가지
1. 처리한 데이터를 뷰에 표시하고 싶을 경우 데이터를 전달하는 역할을 한다.
2. 스프링 MVC에 의해 관리되며, 수동 또는 자동으로 객체를 저장하고 관리하는 기능을 제공한다.
3. Model을 이용하고 싶은 경우 요청 핸들러 메서드의 인수에 Model 타입을 전달한다. 그러면 스프링 MVC가 자동으로 Model 타입 인스턴스를 설정한다.

6-2-2 기억해야 할 중요한 메서드

Model에 객체를 저장하기 위한 메서드는 여러 가지가 준비되어 있지만, 다음 내용은 반드시 기억해 주세요.

addAttribute

특정 이름에 대해 설정한다. 저장하고 싶은 값에 별명을 붙인다고 생각하면 된다. 뷰에서는 별명에 사용한 이름을 이용한다.

6-2-3 Model을 사용하는 프로그램 만들기

package com.example.springmvcmodelsample.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("hello")
public class HelloModelController {

    @GetMapping("model")
    public String helloView(Model model){
        // Model에 데이터를 저장
        model.addAttribute("msg", "타임리프!!!");

        // 반환값으로 뷰 이름을 돌려줌
        return "helloThymeleaf";
    }
}

HelloModelController 클래스

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Hello Thymeleaf</title>
</head>
<body>
<!--  추가-->
<h1 th:text="${msg}">Hello Thymeleaf</h1>
</body>
</html>

helloThymeleaf.html

속성기능 개요
th:text속성값에 지정된 값을 새니타이즈(Sanitize)하여 출력한다
th:utext속성값에 지정된 값을 출력한다(새니타이즈 안 함)

새니타이즈란?
새니타이즈(Sanitize)란 위험한 코드나 데이터를 변환 또는 제거하여 무력화하는 것이다. 간단히 설명하면 '특별한 의미를 가진 문자의 특별함을 무효화하고 의도하지 않은 움직임을 봉쇄'하는 것이다. 새니타이즈는 웹사이트의 입력 폼을 통해 악의적인 코드가 입력되었을 때 등에 유용하게 사용된다.

6-3-1 타임리프 복습

타임리프 특징 세 가지
1. 스프링 부트에서 추천하는 템플릿 엔진이다.
2. HTML로 템플릿을 작성하기 때문에 웹 브라우저로 파일의 내용을 표시하고 확인하면서 뷰를 만들 수 있다.
3. 스프링 부트의 기본 설정으로 src/main/resources/templates 폴더 아래에 '요청 핸들러 메서드의 반환값 + .html' 파일이 참조된다.

6-3-2 타임리프 사용법

직접 문자를 삽입

<h1 th:text="'hello world'">표시하는 부분</h1>

인라인 처리

<h1>안녕하세요! [[${name}]]씨</h1>

[[${}]]를 사용하면 태그를 속성에 추가하는 대신 본문에 변수를 포함할 수 있다. 고정값과 변수를 조합하고 싶은 경우에는 이 방법이 편리하다.

값 결합

<h1 th:text="'오늘의 날씨는 ' + '맑음 ' + '입니다'">표시하는 부분</h1>

+를 이용해 값을 결합할 수 있다.


값 결합(리터럴 치환)

<h1 th:text="|안녕하세요 ${name}씨|">표시하는 부분</h1>

리터럴 치환은 템플릿 언어에서 문자열 내에 변수나 상수 값을 직접 삽입하는 기법을 말한다.

값 결합은 리터럴 치환을 사용하는 것으로 "| 문자 |"로 기술할 수 있다. 문자 안에서 '${}' 표현 식도 함께 사용할 수 있다.


지역 변수

<div th:with="a=1, b=2">
  <span th:text="|${a} + ${b} = ${a+b}|"></span>
</div>

th:with= "변수 이름 = 값"으로 변수에 값을 할당할 수 있다. 변수의 범위는 정의된 태그 내부에서만 사용할 수 있다. 또한 산술 연산자인 +, -, *, /, %를 사용할 수 있다.


비교와 등가

비교 등가 연산자인 >, <, >=, <=, ==, !=를 사용할 수 있다(문자열 비교도 가능)


조건 연산자
삼항 연산자([조건]?[값1]:[값2])를 이용할 수 있다. [조건]이 true일 경우 [값1]이 출력되고, false일 경우 [값2]가 출력된다.


조건 분기(true)

th:if="[조건]"에서 true(참)일 경우 th:if에서 작성한 태그와 자식 요소를 표시한다.


조건 분기(false)

th:unless="[조건]"에서 false(거짓)일 경우, th:unless에서 작성한 태그와 자식 요소를 표시한다.


switch

부모 요소의 th:switch값과 자식 요소에 작성하는 th:case의 값이 동일한 경우, HTML요소를 출력한다. 어떤 값에도 일치하지 않는 값을 출력하는 경우는 th:case="*"를 지정한다.


참조(데이터를 결합한 객체)

캡슐화된 필드를 참조하는 경우 public 접근 제한자의 getXxxx()라는 게터 메서드를 작성해 '객체명.필드' 형식으로 값을 참조할 수 있다. 또 '객체명['필드']'같이 대괄호로도 참조할 수 있다.


참조(th:object)

데이터를 저장한 객체를 'th:object'에 설정하고, 자식 요소에서 '*{필드명}'으로 사용한다.


참조(List)

List나 배열의 요소를 참조할 때는 인덱스 번호를 입력해 참조한다.


참조(Map)
Map 요소를 참조하려면 '키'를 이용하여 값을 참조한다. 'map.key'형식으로도 참조할 수 있다.
또는 map['키']와 같이 대괄호를 사용해 참조할 수도 있다.


반복

th:each="[요소 저장용 변수]: ${[반복 처리하는 객체]}"로 반복 처리할 수 있다. [요소 저장용 변수]는 반복 처리 중에만 유효하다. Iterable 인터페이스를 구현한 클래스라면 th:each로 반복 처리할 수 있다. 자바에서의 확장 for문과 같은 방식이다.


반복 상태

th:each="[요소 저장용 변수],[상태 변수]:[반복 처리할 객체]"와 같이, [요소 저장용 변수]의 선언 다음에 [상태 변수]를 선언하여 반복 상태를 유지한 [상태 변수]를 사용할 수 있다. 반복 상태 변수의 목록은 표 6.2를 참조한다.

표6.2 반복 상태 변수

상태 변수기능 개요
index0부터 시작하는 인덱스. 현재 인덱스를 표시한다.
count1부터 시작하는 인덱스. 현재 인덱스를 표시한다.
size반복 처리하는 객체의 사이즈를 표시한다.
current현재 반복 요소의 객체를 표시한다.
even현재 요소가 짝수 번째인지 여부를 결정한다.
짝수이면 true, 짝수가 아니면 false를 표시한다.
odd현재 요소가 홀수 번째인지 여부를 결정한다.
홀수이면 true, 홀수가 아니면 false를 표시한다.
first현재 요소가 첫 번째 요소인지 여부를 결정한다.
첫 번째이면 true, 첫 번째가 아니면 false를 표시한다.
last현재 요소가 마지막인지 여부를 결정한다.
마지막이면 true,마지막이 아니면 false를 표시한다.

유틸리티 객체

타임리프에서는 자주 사용되는 클래스를 "#name"이라는 상수로 정의하고 있어서 그대로 변수 표현식에서 사용할 수 있다(표 6.3). 데이터를 출력할 때 자주 이용되는 것이 '수치, 일시, 문자열'의 포맷 변환이다.

표6.3 유틸리티 객체 목록

유틸리티 객체기능 개요
#strings문자 관련 편의 기능
#numbers숫자 서식 지원
#bools불리언(Boolean)관련 기능
#datesjava.util.Date 서식 지원
#objects객체 관련 기능
#arrays배열 관련 기능
#listsList 관련 기능
#setsSet 관련 기능
#mapsMap 관련 기능

다른 템플릿 삽입하기

'프래그먼트(fragment)'란 단편이라는 의미다. 프래그먼트화란 여러 템플릿에서 같은 내용이 사용되는 경우 공통 내용을 별개의 파일로 만들고 필요한 부분에 추가하는 것을 말한다.

<!--프래그먼트를 정의-->
<span th:fragment="one">하나</span>
<span th:fragment="two"></span>
<span th:fragment="three"></span>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Fragment를 아래에 삽입하기</h1>
<div id="one" th:insert="fragment :: one"></div>
<div id="three" th:replace="fragment :: three"></div>
</body>
</html>

레이아웃

레이아웃화란 여러 템플릿에서 같은 디자인 레이아웃을 사용하는 경우 공통 레이아웃을 만들고 공유하는 것을 말한다. 레이아웃을 이용하려면 전용 라이브러리인 thymeleaf-layout-dialect가 필요하다.

Thymeleaf Layout Dialect에서는 공통 레이아웃을 Decorator라 하고 공통 레이아웃을 이용하는 측을 Fragment라고 정의한다. Thymeleaf Layout Dialect를 이용할 때의 단점으로는 전체 화면을 타임리프의 변환 처리 후에 확인할 수 있다는 것이다.

공통 레이아웃
머리글, 바닥글, 사이드 메뉴 같은 레이아웃을 가진 애플리케이션을 개발하는 경우 모든 HTML에서 각 요소를 한 덩어리로 묶어 각 페이지마다 따로 작성했다고 하면 머리글을 수정해야 할 경우 모든 HTML을 수정해야 한다. 타임리프의 템플릿 레이아웃 기능을 사용하면 코드의 중복도 줄어들고 공통 부분에 대한 변경도 간단하게 할 수 있다.

profile
개발자 지망생. 일단 하고보자

0개의 댓글