티스토리 뷰

JPA

Mustache

yoooon1212 2024. 10. 4. 09:38

 

Mustache

거의 로직이 없는 템플릿 엔진

 

다양한 프로그래밍 언어에서 사용할 수 있으며, 간단하고 유지보수가 용이한 템플릿을 만드는 데에 유용

 

Spring Boot와 Mustache를 결합함으로써

개발자는 백엔드 로직과 프론트엔드 표현을 분리하여 더 효율적이고 관리하기 쉬운 웹 어플리케이션을 구축할 수 있습니다.

 

 

Mustache의 주요 특징

  • 로직을 최소화한 템플릿(Logic-less templates): Mustache 템플릿은 복잡한 로직을 최소화하여, 템플릿 내에서 간단한 조건문과 반복문을 지원합니다. 이는 데이터를 표시하는 데에 집중하도록 설계되었습니다.
예시 코드
{{#users}}
  <p>{{name}} 님이 로그인했습니다.</p>
{{/users}}
{{^users}}
  <p>로그인한 사용자가 없습니다.</p>
{{/users}}

{{#users}}...{{/users}}는 users 목록에 대한 반복을, {{^users}}...{{/users}}는 users가 비어 있을 때의 처리를 나타냅니다.

  • 언어 독립성(Language agnostic): Mustache는 JavaScript, Java, Python 등 다양한 프로그래밍 언어에서 사용할 수 있습니다.
  • 간단함(Simplicity): 템플릿의 구조가 단순하고 이해하기 쉽습니다.

 

Spring Boot와 Mustache 의 사용

Spring Boot에서 Mustache를 사용하기 위해, 먼저 spring-boot-starter-mustache 의존성을 프로젝트에 추가해야 합니다. 이 스타터는 Mustache 템플릿 엔진과 관련된 모든 필요한 의존성을 제공합니다. 그 후, src/main/resources/templates 디렉토리에 Mustache 템플릿 파일을 위치시키고, Spring MVC 컨트롤러를 통해 모델 데이터를 템플릿에 전달하여 동적인 웹 페이지를 생성할 수 있습니다.

 

build.gradle
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-mustache'
    // ...
}

 

 

Mushtache를 사용해보자

 

SampleController

1. Model 사용
package com.example.demo._domain.blog.controller;

import org.springframework.stereotype.Controller;

	// 주소 설계 - http://localhost:8080/ (GET) 요청
	@GetMapping("/")
	public String home(Model model) {

		// 뷰 리졸버 동작
		// hello --> src/main/resources/templates/hello.mustache
		model.addAttribute("name", "World");
		return "hello";
	}
	
}

 

 

SampleController

2. HttpServletRequest 사용
package com.example.demo._domain.blog.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import jakarta.servlet.http.HttpServletRequest;

	// 주소 설계 - http://localhost:8080/ (GET) 요청
	@GetMapping("/")
	public String home(HttpServletRequest request) {

		// 뷰 리졸버 동작
		// hello --> src/main/resources/templates/hello.mustache
     		request.setAttribute("name", "반가워");
		return "hello";
	}
}

 

templates 에 hello.html 파일을 생성한 후에

hello.mustache로 파일명을 변경합니다.

 

 

hello.mustache 템플릿 파일은 src/main/resources/templates 디렉토리에 위치해야 하며,

이 파일은 Mustache 템플릿 언어를 사용하여 작성됩니다.

간단한 "Hello, World!" 예제를 기반으로 한 hello.mustache 파일의 내용은 다음과 같습니다

<!DOCTYPE html>
<html>
<head>
    <title>Hello Page</title>
</head>
<body>
    <h1>Hello,{{name}}!</h1>
</body>
</html>

 

 

Model 사용 실행 결과

 

 

HttpServletRequest 사용 실행 결과

 

Model은 비지니스 로직과 데이터 처리를 담당할 때 사용하고,

Request는 사용자 요청에 따라 동적으로 데이터를 처리할 때 사용합니다. 

 

일반적으로는 Model을 사용하는 것이 더 좋지만 데이터를 추가하거나 복잡한 로직을 사용할 때는

Request 를 사용하는 것이 좋습니다. 

 

 

application.yml 파일

Mushtache 탬플릿 엔진 설정
spring:
  mustache:
    servlet:
      expose-session-attributes: true  # Mustache 템플릿에서 세션 속성에 접근할 수 있도록 허용
      expose-request-attributes: true  # Mustache 템플릿에서 요청 속성에 접근할 수 있도록 허용

 

expose-session-attributes: true

이 설정이 true로 설정되면, 세션에 저장된 데이터를 Mustache 템플릿에서 사용할 수 있어서

사용자 로그인 상태나 사용자 관련 데이터를 쉽게 표시할 수 있습니다. 

 

expose-request-attributes: true

이 설정이 true로 설정되면, 컨트롤러에서 설정한 요청 속성(Model 에서 추가한 데이터 등)을 템플릿에서 참조하여 사용할 수 있습니다. 

 

 

 

 

 

 


mustache 기본 문법

 

Mustache는 간단하고 직관적인 템플릿 엔진으로,

HTML 등의 템플릿에서 데이터를 삽입하거나 간단한 로직을 표현할 수 있습니다

 

  • {{값}} 데이터 전달
  • {{#값}} 조건문 혹은 반복문(컬렉션)
  • {{^값}} 부정
  • {{>파일명}} 부분 템플릿
  • {{#컬렉션}} -> 내부에 키 값이 없으면 출력할 때ㅡ {{.}} 으로 사용
  • {{{ }}} 콧수염 태그 - 이스케이프 안됨

 

  • 데이터 표시 (Interpolation): {{값}}
    • 설명: 템플릿에 데이터를 삽입할 때 사용합니다.
<p>안녕하세요, {{name}}님!</p>

만약 name에 "홍길동"이란 값이 전달되면, 결과는 <p>안녕하세요, 홍길동님!</p>가 됩니다.

 

 

  • 섹션 (Sections): {{#값}}...{{/값}}
    • 설명: 조건문이나 반복문을 구현할 때 사용합니다. 값이 (또는 참 같은 값)이면 내부 내용을 렌더링합니다.
    • 조건문 예시
{{#isMember}}
  <p>회원 전용 콘텐츠입니다.</p>
{{/isMember}}

isMember가 true일 경우에만 메시지가 표시됩니다.

 

 

반복문 예시

<ul>
  {{#items}}
    <li>{{name}}: {{price}}원</li>
  {{/items}}
</ul>

items가 객체들의 배열이라면, 각 객체의 name과 price를 이용해 리스트를 만듭니다.

 

  • 역섹션 (Inverted Sections): {{^값}}...{{/값}}
    • 설명: 값이 거짓(또는 거짓 같은 값)이면 내부 내용을 렌더링합니다.
    • 예시:
{{^isMember}}
  <p>로그인 후 이용해 주세요.</p>
{{/isMember}}

isMember가 false일 경우에만 메시지가 표시됩니다.

 

  • 부분 템플릿 (Partials): {{>파일명}}
    • 설명: 다른 템플릿 파일을 삽입할 때 사용합니다. 코드의 재사용성을 높여줍니다.
    • 예시:
<header>
  {{> header}}
</header>

현재 템플릿에 header.mustache 파일의 내용을 포함합니다.

 

  • 현재 값 출력: {{.}}
    • 설명: 반복문 내에서 현재 아이템의 값이 키 없이 단순한 값일 때 사용합니다.
    • 예시:
<ul>
  {{#colors}}
    <li>{{.}}</li>
  {{/colors}}
</ul>

colors가 ["빨강", "초록", "파랑"]이라면, 각 문자열 값이 리스트 아이템으로 출력됩니다.

 

 

Mustache 추가 개념 정리

  • 데이터 구조 이해하기: Mustache는 전달된 데이터 모델을 기반으로 렌더링합니다. 따라서 데이터 구조를 잘 이해하고 있어야 올바르게 템플릿을 작성할 수 있습니다.
  • 로직 최소화: Mustache는 템플릿에서의 로직 사용을 최소화하여 뷰와 비즈니스 로직을 분리하는 데 도움을 줍니다.
  • 부분 템플릿 활용: 공통되는 헤더나 푸터 등을 부분 템플릿으로 분리하면 코드의 재사용성과 유지보수성이 높아집니다.
  • HTML 이스케이프: Mustache는 기본적으로 데이터 값을 HTML 이스케이프 처리합니다. 만약 이스케이프를 원하지 않는다면 {{{값}}} 또는 {{& 값}}을 사용할 수 있습니다.

 

예시 코드
<!DOCTYPE html>
<html>
<head>
  <title>{{title}}</title>
</head>
<body>
  {{> header}}

  {{#isMember}}
    <p>안녕하세요, {{name}}님!</p>
    <ul>
      {{#notifications}}
        <li>{{.}}</li>
      {{/notifications}}
    </ul>
  {{/isMember}}

  {{^isMember}}
    <p>로그인해 주세요.</p>
  {{/isMember}}

  {{> footer}}
</body>
</html>

 

 


머스태치 태그 연습

 

IndexController
package com.example.demo._domain.blog.controller;

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


@Controller // 뷰 리졸버 타겠끔 생성
public class IndexController {

	
	// 정적 파일 -> 어떤 폴더에 넣어야 하는가? -> static 폴더
	// http://localhost:8080/index
	@GetMapping({"/index", "/index2"})
	public String index1(Model model) {
		// 뷰 쪽으로 내려줄 데이터를 만들어 보자
		String name = "길동";
		int age = 22;
		String email = "<b>a@naver.com</b>";
		String password = "asd123";
		
		model.addAttribute("name", name);
		model.addAttribute("age", age);
		model.addAttribute("email", email);
		model.addAttribute("password", password);
		
		// viewResolver 동작
		// src/main/resources/templates/index.mushtache 를 찾을 수 있도록 파일 생성
		return "index";
	}
}

 


templates 에서 index.html 파일 생성 후 

index.mustache로 파일명 변경

 

머스태치 코드 추가

index.mustache 
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<p>안녕하세요, {{name}}님!</p>
	<p> {{name}}님의 나이는 {{age}}세군요.</p>
	<p> {{name}}님의 이메일 주소는 {{{email}}}입니다.<p>
	
	<p>{{email}} VS {{{email}}}</p>
</body>
</html>

 

실행결과

 

 

이때 {{email}}과 {{{email}}} 차이를 확인할 수 있다. 

 

 

application.properties 코드 추가
spring.application.name=class_mustache

# HTTP 응답의 인코딩을 강제로 UTF-8로 설정합니다.
# 즉, 모든 서버 응답에서 UTF-8 인코딩을 사용하도록 강제합니다.
server.servlet.encoding.force-response=true

# HTTP 요청과 응답에 사용되는 기본 문자 인코딩을 UTF-8로 설정합니다.
# 이 설정은 클라이언트와 서버 간의 통신에서 UTF-8 인코딩을 사용하도록 합니다.
spring.http.encoding.charset=UTF-8

# HTTP 인코딩 기능을 활성화합니다.
# 이 옵션이 true로 설정되면 스프링 부트는 HTTP 요청과 응답에서 설정된 문자 인코딩을 사용합니다.
spring.http.encoding.enabled=true

# 모든 HTTP 요청 및 응답에 대해 UTF-8 인코딩을 강제합니다.
# 클라이언트가 별도의 인코딩을 지정하지 않더라도 UTF-8 인코딩이 사용됩니다.
spring.http.encoding.force=true

spring.output.ansi.enabled=always

 

 


 

GetMapping 없이도 static 폴더에 있는 html 파일을 렌더링하는 방법

 

정적 자원 

서버에서 클라이언트에게 직접 전송되는 파일들로, 서버 측에서 변경되지 않고 그대로 제공된다. 

예를 들어,  HTML, CSS, JS, 이미지 등은 서버에서 처리되는 로직 없이 그대로 클라이언트에게 전달된다.

 

 

정적 자원 처리 방식

웹 애플리케이션에서 HTML, CSS, JS, 이미지 등과 같은 파일을 클라이언트에게 직접 제공하는 방법

 

 

정적 자원 저장 위치

  • src/main/resources/static
  • src/main/resources/public
  • src/main/resources/resources
  • src/main/resources/META-INF/resources

이 폴더에 위치하는 파일들은 특별한 설정 없이도 자동으로 제공된다. 

 

정적 자원에 접근하려면 클라이언트는 URL을 통해 요청을 보낸다.

src/main/resources/static/home.html 파일이 있다면 클라이언트는 http://localhost:8080/home.html로 접근한다.

spring boot는 이 url 요청을 처리하여 static 폴더에서 home.html 파일을 찾는다. 

 

 

연습 예시

 

static 폴더에 home.html 파일 생성

 

home.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<span>
		여기는 정적 파일 home.html 입니다. 
	</span>
</body>
</html>

 

http://localhost:8080/home.html

 

실행결과

정적 자원이라 java 연산이 필요 없음

 

 

'JPA' 카테고리의 다른 글

게시글 만들기 - 프로젝트 생성  (0) 2024.10.10
템플릿 엔진  (0) 2024.10.04
글 수정 API 만들기  (0) 2024.10.02
글 상세보기(조회) API 구현  (0) 2024.10.02
글 목록 조회 API 만들기  (0) 2024.10.02
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함