[Spring] Mustache

전주은·2022년 12월 15일
0
post-thumbnail

정의(소개)

템플릿 엔진

  • 템플릿 엔진은 템플릿의 문법과 데이터(JSON, XML 등)를 이용해서 HTML 문서를 만들어주는 소프트웨어라 이해하면 된다.
  • 서버 템플릿 엔진 (서버에서 동작)
    - JSP, Freemarker, Thymeleaf 와 같이 서블릿(서버)에서 동작하는 템플릿
    - Springboot 에서는 JSP 를 사용하는 것을 권장하지 않는다.
    - Springboot 에서는 Thymeleaf 를 적극적으로 밀어주는 것 같다. 하지만 문법이 어렵기 때문에 입문으로 하기에는 쉽지는 않아보인다.
  • 클라이언트 템플릿 엔진 (브라우저 위에서 동작)
    - React, Vue, Anguler 와 같이 서버에서 가져온 데이터(JSON, XML 등)를 가지고 웹 화면을 꾸며주는 라이브러리(혹은 프레임워크)
    - SPA(Single Page Application) 환경으로 웹 서비스를 개발하는 업체가 점점 늘어나면서 많이 사용되고 있다.

Mustache

  • Mustache 는 Springboot 에서 공식으로 지원하는 템플릿 엔진이다. 매우 심플한 문법으로 배워서 그 즉시 적용할 수 있을 정도로 심플하다.
  • Mustache 는 JAVA 뿐만 아니라 현존하는 대부분의 언어를 지원하고 있다. 예를들어 JAVA 에서 사용될 때는 서버 템플릿 엔진으로, Javascript 에서 사용될 때는 클라이언트 템플릿 엔진으로 사용할 수 있는 장점이 있다.
  • 로직 코드가 없어서(Logic-less templates) 뷰(View)의 역할에 충실하여, 서버와 역할을 분리할 수 있다.
    ex) JSP 의 경우는 <% %> 안에 있는 JAVA 문법은 서버단에서, Javascirpt 는 클라이언트단에서 동작하기 때문에 하나의 JSP 파일 안에서 서버와 클라이언트 코드가 뒤섞이는 등의 문제가 있어 유지보수를 하기에 어려움이 있다.

장점 및 단점

장점

  • JSP 와 Thymeleaf 는 IntelliJ Ultimate 버전에서만 사용가능하지만, Mustache 는 Community 버전에서도 사용이 가능하다.
  • 문법이 다른 템플릿 엔진보다 심플
  • 로직 코드를 사용할 수 없어서 View의 역할과 서버의 역할을 명확하게 분리
  • Mustache.js와 Mustache.java 2가지가 다 있어서, 하나의 문법으로 클라이언트/서버 템플릿 모두 사용 가능

스프링에 적용 방법

  • Plugins 메뉴에서 Mustache 를 검색하여 설치한다. 설치한 뒤에는 재시작 필수!

  • build.gradle 에 의존성 등록.

compile('org.springframework.boot:spring-boot-starter-mustache')
  • Mustache 파일의 위치는 기본적으로 src/main/resource/templates 이고, 이 디렉토리 안에 *.mustache 파일을 만들면 된다.
@Controller
public class IndexController {

	@GetMapping("/")
	public String index(Model model){
	     return "index";
	}
}

mustache 를 사용하게 되면 앞에 경로(src/main/resources/templates)와 뒤에 확장자(.mustache)는 생략을 한 순수한 파일의 이름만 반환하면 된다.
index 를 반환하게 되면 src/main/resources/templates/index.mustache 로 변환되어 View Resolver 가 처리하게 된다.

간단한 문법 소개

변수

{{와 }} 사이에 변수 이름을 입력합니다. 문자열은 자동으로 HTML 이스케이프가 되어 출력되는데 만약 이스케이프 되지 않은 문자열을 출력하고 싶다면 {{{와 }}}를 사용합니다.
데이터

{
  "name" : "Chris",
  "company" : "<b>Github</b>"
}

템플릿

* {{name}}
* {{age}}
* {{company}}
* {{{company}}}

결과

* Chris
*
* &lt;b&gt;Github&lt;/b&gt;
* <b>Github</b>

두 번째 줄의 {{age}}는 age가 없는 변수이므로 아무런 값도 출력되지 않습니다. 네 번째 줄에서는 콧수염 세 개를 사용했기 때문에 HTML이 이스케이프 되지 않고 그대로 출력됩니다. 출력 결과를 웹 브라우저에서 보았다면 네 번째 줄은 굵은 글씨로 표시될 것입니다.

객체 안에 또 객체가 포함된 복잡한 객체

데이터

{
  "name" : "Chris",
  "company" : {
    "name" : "Github",
    "address" : {
      "country" : "USA"
    }
  }
}

템플릿

Country : {{company.address.country}}

결과

Country : USA

섹션

섹션section 문법은 조건문이나 반복문 대신 사용됩니다. 주어진 값에 따라 조건문이나 반복문으로 사용되는데 {{#변수명}}으로 시작하고 {{/변수명}}으로 끝납니다. 변수가 배열이면 반복문으로 그렇지 않으면 조건문으로 사용되는데 0, false, 빈 문자열은 거짓으로 평가되므로 섹션의 내용이 출력되지 않습니다.
조건문
변수의 값이 배열이 아니면 조건문으로 사용됩니다. 단, 배열이라 하더라도 빈 배열은 거짓 조건문과 마찬가지로 취급되어 섹션의 내용이 출력되지 않습니다. 다음은 false 또는 비슷한 값을 변수로 사용했을 때의 결과입니다.
데이터

{
  "person" : false
}

템플릿

출력됩니다.
{{#person}}
  출력안됩니다.
{{/person}}

결과

출력됩니다.

데이터가 객체일때

{
  "person" : {"name" : "Jon"}
}

템플릿

{{#person}}
  {{name}}
{{/person}}

결과

  Jon

섹션 안에서는 섹션 변수의 속성을 마치 변수처럼 사용할 수 있습니다.

섹션 내에서 다른 루트 변수에 접근할 때
데이터

{
  "person" : {"name" : "Jon"},
  "company" : {"name" : "Google"}
}

템플릿

{{#person}}
  {{name}}의 회사는 {{company.name}}입니다.
{{/person}}

결과
반복문
변수의 값이 배열이면 반복문이 됩니다. 앞에서 말했듯이 빈 배열은 거짓 조건문으로 취급됩니다.
데이터

{
  "repo" : [
    { "name" : "resque" },
    { "name" : "hub" },
    { "name" : "rip" }
  ]
}

템플릿

{{#repo}}
  <b>{{name}}</b>
{{/repo}}

결과

<b>resque</b>
<b>hub</b>
<b>rip</b>

반전섹션(else)

섹션과 반대되는 조건에서만 출력되는 블럭입니다. 즉, 섹션에 사용된 없는 변수이거나 변수의 값이 false 또는 이와 비슷한 값(0, 빈 문자열)이거나 빈 배열일 때만 출력됩니다. 반전 섹션은 {{^변수}}로 시작하고 {{/변수}}로 끝납니다.
데이터

{
  "repo": []
}

템플릿

{{#repo}}
  <b>{{name}}</b>
{{/repo}}
{{^repo}}
  저장소가 없음
{{/repo}}

결과

 저장소가 없음

주석

템플릿 코드에는 존재하지만 화면에는 출력되지 않는 코드를 작성할 때 사용합니다. 주석은 {{! 주석 }}과 같이 작성합니다. 다음과 같은 템플릿이 있다고 생각해봅시다.
템플릿

<h1>Today{{! 주석 }}</h1>

결과

<h1>Today</h1>

부분템플릿

부분템플릿(Partials)은 외부 파일을 템플릿의 일부로 불러올 수 있는 기능으로서 {{> 파일이름}}과 같이 사용합니다. 다음은 base라는 템플릿 파일에서 user라는 부분템플릿을 불러오는 예제입니다.

base.mustache 파일:
<h2>Names</h2>
{{#names}}
  {{> user}}
{{/names}}

user.mustache 파일:
<strong>{{name}}</strong>

=

<h2>Names</h2>
{{#names}}
  <strong>{{name}}</strong>
{{/names}}

참고문서

https://engineer-mole.tistory.com/123
https://m.blog.naver.com/nuberus/221884812398
https://velog.io/@roo333/Mustache-1
https://github.com/janl/mustache.js/
https://taegon.kim/archives/4910

0개의 댓글