Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

Handlebars에서 if문에 헬퍼함수 사용하기

handlebars는 템플릿 언어인 Mustache를 확장한 템플릿 라이브러리이다. handlebars를 소개하는 글은 아니지만 처음 보는 사람들을 위해서 간단히 설명하자면 다음과 같이 템플릿을 정의한다.

<script id="example-template" type="text/x-handlebars-template">
  <ul>
    {{#each members}}
      <li>{{name}}
    {{/each}}
  </ul>
</script>

<script> 태그를 사용해서 정의해야 하는 것은 아니고 그냥 템플릿 문자열이면 되기는 하지만 개인적으로는 관리하기도 변하고 작성도 편해서 <script> 태그를 이용하는 방법을 좋아한다.

<script type="text/javascript" src="/components/handlebars.js/handlebars.js"></script>
<script type="text/javascript">
  window.addEventListener('load', function(evt) {
    var m = {
      members: [
        {name: 'outsider'},
        {name: 'zziuni'},
        {name: 'danni'},
        {name: 'fallroot'},
        {name: 'boxer'},
        {name: 'aj'},
        {name: 'insane'},
        {name: 'j2p'}
      ]
    }
    var source = document.getElementById('example-template').innerHTML;
    var tmpl = Handlebars.compile(source);
    document.getElementById('wrap').innerHTML = tmpl(m)
  }, false);
</script>

앞에서 정의한 템플릿을 위와 같이 사용한다. <script> 태그로 정의한 템플릿을 가져와서 handlebars로 컴파일해서 템플릿으로 만들고 템플릿에 객체를 전달해서 HTML을 생성한다. 여기서는 wrap라는 <div>에 변환된 <li>를 넣도록 만들었다.

이제 <li>태그를 만들때 name이 모음으로 시작하는 경우에는 다른 스타일을 주기 위해서 if 문을 사용한다고 해보자.

{{#each members}}
  {{#if @index % 2 == 0}}
    <li class="vowel">{{name}}</li>
  {{else}}
    <li class="consonant">{{name}}</li>
  {{/if}}
{{/each}}

템플릿을 위와 같이 작성하기 쉽지만 handlebars는 저런식의 if문을 제공하지 않는다. if자제가 헬퍼메서드로 등록되어 있는데 if 헬퍼함수에 전달한 값을 true/false 여부만 판단할 뿐이고 일반적인 자바스크립트처럼 저런식의 표현식은 제공하지 않는다. {{#if name}}과 같은 정도로만 사용할 수 있고 name을 가지고 true/false 여부만 판단한다.(name은 값이 존재하므로 저렇게 사용하면 여기서는 항상 true이다.)

하지만 당연히 간단한 if문 외에 로직이 필요한 if문이 필요하게 마련인데 이는 직접 헬퍼함수를 등록해서 해결할 수 있다.

Handlebars.registerHelper('isVowel', function(options) {
  var regexp = /^[aeiou]/;
  if (regexp.test(this.name)) {
    return options.fn(this);
  } else {
    return options.inverse(this);
  }
});

헬퍼함수는 Handlebars.registerHelper()를 사용해서 등록할 수 있고 첫 인자가 헬퍼함수의 이름이고 두번째 함수가 헬퍼함수이다. 헬퍼함수는 기본적으로 options라는 객체를 인자로 받는데 이는 자동으로 전달되는 인자이다. 즉 options만 받도록 작성했다는 것은 전달하는 인자가 없다는 것으로 인자가 있다면 자동으로 앞에 붙는다. 즉 인자가 1개 있으면 function(arg1, options) {} 처럼 작성해야 한다. 여기서는 isVowel이라는 헬퍼함수를 if문처럼 사용할 것이므로 원하는 조건(여기서는 이름이 문자로 시작하면)이 true이면 options.fn(this)를 반환해서 if 구문의 내용을 사용하고 false이면 options.inverse(this)를 반환해서 else 구문을 사용하도록 작성했다. handlebars에서는 대부분 그런데 this에 현재 컨텍스트의 값이 들어간다.(여기서는 each문으로 돌아가는 members의 값들..)

<ul>
  {{#each members}}
    {{#isVowel}}
      <li class="vowel">{{name}}</li>
    {{else}}
      <li class="consonant">{{name}}</li>
    {{/isVowel}}
  {{/each}}
</ul>

템플릿은 위와 같이 작성한다. if문대신에 isVowel 헬퍼함수를 사용했다.({{/isVowel}}로 닫아준 것에 주의!!) else문은 그대로 사용하고 이렇게 사용하면 원하는 조건으로 if문을 사용할 수 있다. 물론 헬퍼함수에 파라미터가 필요하다면 전달해주면 된다.
2013/05/13 23:53 2013/05/13 23:53