본문 바로가기
웹 프로그래밍/JavaScript

handlebars 템플릿

by Backchus 2019. 8. 20.

Handlebars는 시맨틱한 템플릿을 효과적으로 구축하는데 필요한 기능을 제공합니다.

또한 템플릿을 JavaScript함수로 컴파일하기 때문에 대부분의 다른 템플릿 엔진보다 템플릿을 더 빠르게 실행할 수 있습니다.

 

실습 01(기본 예제)

실습을 위해 다음과 같이 html문서 안에 template코드를 만듭니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html>
  <head>
    <style></style>
  </head>
  <body>
    <h1>template using handlebar</h1>
 
    <section class="show">
 
</section>
 
    <script type="myTemplate" id="listTemplate">
        <li>
         <div>게시자 : {{name}}</div>
         <div class="content">{{content}}</div>
         <div>좋아요 갯수 <span> {{like}} </span></div>
         <div class="comment">
           <div>{{comment}}</div>
         </div>
      </li>
    </script>
  </body>
</html>
 
 

 

Handlebars를 설치합니다.

  1. https://cdnjs.com/libraries/handlebars.js/ 로 접속
  2. 목록에 적당한 CDN 경로를 복사.
  3. html파일 하단에 경로를 추가
1
cs

 

template변수에 위에 선언했던 템플릿노드를 불러오고 Handlebars.compile을 활용하여 template을 매개로 템플릿을 컴파일합니다. Handlebars.complie함수는 템플릿 문자를 매개로 받아와서 나중에 데이터에 대해 템플릿을 만들 수 있도록 미리 준비하기 위한 함수를 반환합니다.

따라서 bindTemplate함수로 템플릿 작업을 할 수 있습니다.

1
2
3
4
<script>
      var template = document.querySelector("#listTemplate").innerText;
      var bindTemplate = Handlebars.compile(template); //bindTemplate은 메서드입니다.
</script>
 

 

임의로 데이터를 추가합니다.

1
2
3
4
5
6
7
var data = {
        id: 88,
        name"crong",
        content"새로운글을 올렸어요",
        like: 5,
        comment: "댓글이다"
      };
 

 

이렇게 bindTemplate함수에 data객체를 매개로 실행을 시키면 아래 주석과 같은 결과가 나옵니다.

resultTemplate을 DOM조작을 이용해 필요한 부분에 삽입을 해주면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 var data = {
        id: 88,
        name"crong",
        content"새로운글을 올렸어요",
        like: 5,
        comment: "댓글이다"
      };
 
      var template = document.querySelector("#listTemplate").innerText;
      var bindTemplate = Handlebars.compile(template); //bindTemplate은 메서드입니다.
 
      var resultTemplate = bindTemplate(data);
      console.log(resultTemplate);
      /*
      <li>
         <div>게시자 : crong</div>
         <div class="content">새로운글을 올렸어요</div>
         <div>좋아요 갯수 <span> 5 </span></div>
         <div class="comment">
           <div>댓글이다</div>
         </div>
      </li>
      */
 

 

실습 02(배열이 포함된 데이터의 처리)

에를 들면 댓글 목록을 위한 템플릿 처리를 해야 하는 경우 댓글이 1개 이상일 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var data = {
      "id" : 88,
    "name" : "crong",
    "content" : "새로운글을 올렸어요",
    "like" : 5
    "comment" : ["댓글이다""멋진글이네요""잘봤습니다"]
};
 
bindTemplate(data);
 
/*
      <li>
         <div>게시자 : crong</div>
         <div class="content">새로운글을 올렸어요</div>
         <div>좋아요 갯수 <span> 5 </span></div>
         <div class="comment">
           <div>댓글이다,멋진글이네요,잘봤습니다</div>
         </div>
      </li>
*/
 
cs

 

위에 코드의 결과는 주석에 class값이 comment인 부분처럼 배열 안에 값이 이어져서 나옵니다. 하지만 저렇게 나오길 의도한 게 아니죠. 각자 div 태그를 만들어 하나씩 삽입을 하고 싶을 경우 handlebars 템플릿 내에 간단한 문법으로 해결할 수 있습니다.

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
<script type="myTemplate" id="listTemplate">
      <li>
          <div>게시자 : {{name}}</div>
          <div class="content">{{content}}</div>
          <div>좋아요 갯수 <span> {{like}} </span></div>
          <div class="comment">
          <h3>댓글목록</h3>
          {{#each comment}}
              <div>{{@index}}번째 댓글 : {{this}}</div>
          {{/each}}
          </div>
      </li>
    </script>
/*
 
      <li>
          <div>게시자 : crong</div>
          <div class="content">새로운글을 올렸어요</div>
          <div>좋아요 갯수 <span> 5 </span></div>
          <div class="comment">
          <h3>댓글목록</h3>
              <div>0번째 댓글 : 댓글이다</div>
              <div>1번째 댓글 : 멋진글이네요</div>
              <div>2번째 댓글 : 잘봤습니다</div>
          </div>
      </li>
*/
 
 

#each라는 키워드를 이용하여 comment프로퍼티에 포함되어있는 값을 반복적으로 하나씩 꺼내서 그안에있는 템플릿에 매핑하게 됩니다. 또한 @index를 통해 값을 자연스럽게 0부터 하나씩 증가하는 인덱스를 얻을 수 있습니다.

실습 03(data자체가 많아진 경우의 처리)

1
2
3
4
5
6
var data = [
    {"id" : 88"name" : "crong""content" : "새로운글을 올렸어요""like" : 5"comment" : ["댓글이다""잘했어요"]},
    {"id" : 28"name" : "hary""content" : "전 오늘도 노래를 불렀어요""like" : 0"comment" : ["제발고만..","듣고싶네요 그노래"]},
    {"id" : 23"name" : "pororo""content" : "크롱이 항상 말썽을 피워서 행복해~""like" : 4"comment" : []},
    {"id" : 5"name" : "pobi""content" : "물고기를 한마리도 잡지 못하다니..""like" : 5"comment" : ["댓글이다""멋진글이네요""잘봤습니다"]}
];
 
 

 

이런 경우 반복적으로 결과를 forEach 또는 reduce를 사용해서 합칠 수 있습니다.

forEach

1
2
3
4
5
var innerHtml = "";
 
data.forEach(function (item, index) {
    innerHtml += bindTemplate(item);
});
 
 

 

reduce

1
2
3
var innerHtml = data.reduce(function(prve, next) {
    return prve + bindTemplate(next);
}, "");
 
 

 

실습 04(조건 상황에 따른 처리)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script type="myTemplate" id="listTemplate">
    <li>
        <div>게시자 : {{name}}</div>
        <div class="content">{{content}}</div>
        <div>좋아요 갯수 <span> {{like}} </span></div>
        <div class="comment">
        <h3>댓글목록</h3>
        {{#if comment}}
            {{#each comment}}
                <div>{{@index}}번째 댓글 : {{this}}</div>
            {{/each}}
        {{else}}
            <div>댓글이 아직 없군요</div>
        {{/if}}
        </div>
    </li>
</script>
 
 

댓글목록이 없는 경우 따로 없다고 댓글을 달기 위해 #if를 이용해서 템플릿을 만들어줍니다.

결과적으로 실습 03의 데이터를 다시 처리하면 최종적으로 이런 결과가 나옵니다.

참고자료: https://handlebars-draft.knappi.org/

 

Handlebars (draft)

 

handlebars-draft.knappi.org

참고자료: https://www.edwith.org/boostcourse-web/lecture/16784/

 

[LECTURE] 2) handlebar를 활용한 템플릿 작업 : edwith

들어가기 전에 templating작업은 ES2015에서 template literal로 좀 더 간단해지긴 했습니다. 하지만 여전히 다양한 조건 상황에서의 처리 등은 여전히 복잡합니... - 윤지수

www.edwith.org

 

'웹 프로그래밍 > JavaScript' 카테고리의 다른 글

정규표현식  (0) 2019.09.13
객체 리터럴과 this  (0) 2019.08.19
자바스크립트 객체  (0) 2019.08.03
자바스크립트 배열  (0) 2019.08.02
Browser Event, Event object, Event handler  (0) 2019.02.07