Web/기타

[mustache] spring boot와 mustache 2

  • -

먼저 mustache에서 사용할 데이터를 설정하는 dto를 작성해보자.

DTO

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class NoteBook {
    private String model;
    private int price;
}

 

attribute 출력

 

{{attribute_name}}

model에 담긴 attribute를 출력하기 위해서는 {{attribute_name}}을 사용한다.  이 경우는 text 형태로 attribute의 내용을 단순 출력하는데 간혹 html 형태로 출력하려는 경우 {{{attribute_name}}} 형태나 {{&attribute_name}}을 사용하면 된다.

<ul>
	<li>text로 출력: {{ org }}</li>
	<li>html로 출력 1: {{{org}}}</li>
	<li>html로 출력 2: {{&org}}</li>
</ul>

출력 결과는 아래와 같다.

한가지 아쉬운 점은 null이나 존재하지 않는 값을 사용하면 오류가 발생한다는 점이다. (공백이나 빈 문자열은 무관)

현재는 없는 값: {{ some }}


-- 오류 
There was an unexpected error (type=Internal Server Error, status=500).
No method or field with name 'some' on line 15
com.samskivert.mustache.MustacheException$Context: No method or field with name 'some' on line 15

따라서 값을 확실히 채워서 보내던가 아래 나오는 section을 이용해야 한다.

 

section

section은 {{#attribute_name}}과 {{/attribute_name}} 형태를 사용하는데 attribute의 값에 따라서 동작이 달라진다.

true/false

model.getAttribute(attribute_name)값이 true/false인 경우는 조건문 처럼 동작한다. 따라서 true인 경우는 section이 동작하고 false인 경우는 동작하지 않는다. 이 동작은 값이 null인 경우와 null이 아닌 경우도 동일하다.

model.addAttribute("false_value", false);
model.addAttribute("true_value", true);

 

따라서 아래의 경우 "여긴 나온다"만 출력된다.

{{# false_value }}
여긴 안나온다.
{{/ false_value  }}

{{# true_value }}
여긴 나온다.
{{/ true_value }}

 

collection

collection의 경우 반복문으로 사용된다. 

model.addAttribute("strs", Arrays.asList("Hello", "mustache", "world"));

반복문 내에서 요소에 접근할 때에는 .을 사용할 수 있다.

<ul>
	{{# strs }}
	<li>{{ .  }}</li>
	{{/ strs }}
</ul>

 

collection 내부에 DTO나 map 처럼 property가 있는 객체는 section 내부에서 property이름을 직접 사용할 수도 있다.

model.addAttribute("notebooks",
	Arrays.asList(NoteBook.builder().model("LG 그램").price(11000).build(),
		NoteBook.builder().model("갤럭시 북").price(10000).build(),
		NoteBook.builder().model("맥북프로").price(15000).build()));
<ul>
	{{# notebooks }}
	<li>{{ model }}, {{ price }}</li>
	{{/ notebooks }}
</ul>

 

나머지 경우는 값

위에서 언급한 나머지 경우는 값으로 판단된다. 따라서 출력 될 수 있고 값의 타입이 property를 갖는 dto형태나 map의 경우는 key를 이용해서 value에 접근할 수 있다.

model.addAttribute("notebook", NoteBook.builder().model("LG 그램").price(11000).build());

Map<String, Object> info = new HashMap<>();
info.put("name", "홍길동");
info.put("age", 20);
model.addAttribute("info", info);

 

{{# notebook }}
	<ul>
		<li>{{ model }}</li>
		<li>{{ price }}</li>
	</ul>
{{/ notebook }}

{{# info }}
	<ul>
		<li>{{ name }}</li>
		<li>{{ age }}</li>
	</ul>
{{/ info }}

 

 

부정

section에서 ^를 사용하면 inverted section이 되어서 boolean 타입에 대해 부정을 선언할 수 있다.

{{^ false_value }}
아직 값이 없어요
{{/ false_value }}

inverted section은 boolean 뿐 아니라 collection에 대해서도 사용할 수 있다.

 

기타

 

include 처리

대부분 script 언어들은 header와 footer를 include 해서 처리한다. mustache역시 이런 기능을 제공하는데 {{> 삽입할페이지}} 형태를 사용한다.

<!-- template/include/header.mustache -->
<h1>안녕 Mustache</h1>
<hr />

 

<!-- template/index.mustache -->
<!DOCTYPE html>
<html lang="ko">
  <body>
    {{> /include/header }}
    <h1>값의 출력</h1>
    ...
  </body>
</html>

 

주석

주석을 사용하려면 {{! }}를 사용한다.

{{! null 값을 판단할 수 없다면 section을 이용해야 한다.}}

괜히 html 주석을 만들어놓고 클라이언트에 정보를 전달하는 불상사가 없도록 하자.

 

벌써 끝인가??? 일단 공식 가이드에서 나온 기능들은 쭉 살펴봤다. 기능은 적지만 사실 일반적인 웹페이지를 작성하기에 부족합은 없어보인다. 

갈수록 SPA 등으로 공부해야할 것도 많은 시기에 복잡한 템플릿 엔진 대신 mustache를 써보는 것도 좋은 대안인것 같다.

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.