[handlebars] Getting Started

Getting Started handlebars

from : http://handlebarsjs.com/

Getting Started

Handlebars는 아래와 같이 일반 HTML과 같이 보인다.
내부에는 내장된 handlebars 표현식 {{ 와 }}로 표현하고 있다.

<div class="entry">
  <h1>{{title}}</h1>
  <div class="body">
    {{body}}
  </div>
</div>
그리고 <script>태그 안에 포함시켜 브라우저로 전달할 수 있도록 한다.
다음과 같다.

<script id="entry-template" type="text/x-handlebars-template">
  <div class="entry">
    <h1>{{title}}</h1>
    <div class="body">
      {{body}}
    </div>
  </div>
</script>
JavaScript에서 컴파일 하기 위해서 Handlebars.compile를 이용할 수 있다.
var source   = $("#entry-template").html();
var template = Handlebars.compile(source); 
또한 미리 컴파일 해 둘 수 있다.

- 실행시 필요한 라이브러리 최소화
- 브라우저에서 컴파일 하는 자원낭비를 막을 수 있다.
- 모바일 디바이스에서 수행할때 꼭 필요한 작업이라고 할 수 있다.

context 값을 이용하여 template를 실행하는 방법은 다음과 같다.
var context = {title: "My New Post", body: "This is my first post!"};
var html    = template(context);
결과는 다음과 같다.
<div class="entry">
  <h1>My New Post</h1>
  <div class="body">
    This is my first post!
  </div>
</div>
즉 {{ }} 표현식으로 된 내용이 context의 내용으로 변환되었다.

HTML Escaping

Handlebars HTML-escapes값은 {{표현식}} 으로 반환된다. 만약 escape를 원하지 않는다면 {{{ }}} 표현식을 이용하면 된다. 이는 triple-stash라고 부른다.
<div class="entry">
  <h1>{{title}}</h1>
  <div class="body">
    {{{body}}}
  </div>
</div>
context는 다음과 같다.
{
  title: "All about <p> Tags",
  body: "<p>This is a post about &lt;p&gt; tags</p>"
}
결과는 다음과 같다.
<div class="entry">
  <h1>All About &lt;p&gt; Tags</h1>
  <div class="body">
    <p>This is a post about &lt;p&gt; tags</p>
  </div>
</div>
Handlebars.SafeString을 이용하면 escape하지 않는다. 만약 helper를 작성하고 이것이 HTML을 생성하는 것이라면 new Handlebars.SafeString(result)를 이용하면 된다.
이런 환경에서 수동적으로 파라미터를 이스케이프 할 수 있다.
Handlebars.registerHelper('link', function(text, url) {
  text = Handlebars.Utils.escapeExpression(text);
  url  = Handlebars.Utils.escapeExpression(url);
  var result = '<a href="' + url + '">' + text + '</a>';
  return new Handlebars.SafeString(result);
});
이 코드는 파라미터로 전달된 내용을 이스케이프 할 것이다. 그러나 결과 값으로 safe로 마크하게 된다. 그러므로 Handlebars는 "triple-stash"를 기술하지 않더라도 이스케이프 처리를 하지 않게 된다.

Block Expressions

Block Expressions는 헬퍼를 지정하도록 해준다. 이것은 현재와 다른 서로다른 컨텍스트에서 템플릿 섹션을 invoke하게 해준다.
이 블록 헬퍼들은 # 시작하고 마지막으로는 /로 끝이 나는 블록을 가진다.

다음 HTML내용을 살펴보자. 이는 HTML리스트를 생성하게 된다.
{{#list people}}{{firstName}} {{lastName}}{{/list}}
context : 
{
  people: [
    {firstName: "Yehuda", lastName: "Katz"},
    {firstName: "Carl", lastName: "Lerche"},
    {firstName: "Alan", lastName: "Johnson"}
  ]
}
이 헬퍼 이름을 list로 생성하고자 한다고 하자.
헬퍼는 people을 첫번째 파라미터로 받는다. 그리고 옵션들의 해시는 두번째 파라미터로 받는다.
옵션 해시는 fn으로 이름된 속성을 가지고 있다. 이는 컨텍스트와 함께 호출할 수 있으며, 일반적으로 Hanglebars template처럼 invoke하게 된다.

Handlebars.registerHelper('list', function(items, options) {
  var out = "<ul>";
  for(var i=0, l=items.length; i<l; i++) {
    out = out + "<li>" + options.fn(items[i]) + "</li>";
  }
  return out + "</ul>";
});
템플릿을 실행하면 다음과 같은 결과가 나온다.
<ul>
  <li>Yehuda Katz</li>
  <li>Carl Lerche</li>
  <li>Alan Johnson</li>
</ul> 
Block helper는 더 많은 기능이 있다. else섹션 생성 등...
options.fn(context)를 호출할때 블록헬퍼의 컨텐츠는 escape된다. 그리고 Handlebars는 블록헬퍼의 결과를 escape하지 않는다. 만약 Handlebars가 escape 처리를 하게 된다면 두번 escape되기 때문이다.

Handlebars Paths

Handlebars는 단순 패스를 지원한다. Mustache와 같이..
<p>{{name}}</p>
다음과 같은 중첩 path도 지원한다. 
<div class="entry">
  <h1>{{title}}</h1>
  <h2>By {{author.name}}</h2>
  <div class="body">
    {{body}}
  </div>
</div>
context :
var context = {
  title: "My First Blog Post!",
  author: {
    id: 47,
    name: "Yehuda Katz"
  },
  body: "My first post. Wheeeee!"
};
이는 Handlebars가 좀더 raw한 JSON 객체와 함게 템플릿을 처리할 수 있다는 것을 의미한다.

또한 ../세그먼트를 포함할 수 있으며, 이는 부모로 부터 상대적인 경로를 나타낸다.
<h1>Comments</h1>
<div id="comments">
  {{#each comments}}
  <h2><a href="/posts/{{../permalink}}#{{id}}">{{title}}</a></h2>
  <div>{{body}}</div>
  {{/each}}
</div>
../ 는 호출하는 블록마다 다르게 해석이 될 것이다.
../를 이용하는 것은 컨텍스트가 변경될때 필요하다. 그러므로 each와 같은 헬퍼들의 자식은 ../의 사용이 if와 같은 헬퍼의 자식에 따라 사용하거나 하지않게 작업이 필요할 것이다.

{{permalink}}
{{#each comments}}
  {{../permalink}}
  {{#if title}}
    {{../permalink}}
  {{/if}}
{{/each}}
이 예제에서 서로다른 블록에서 permalink 값이 존재하더라도 같이 사용될 것이다.
이러한 행위는 Handlebars4에서 지원이 된다.

Handlebars는 this키워드를 이용하여 helpers와 data fields에 대해서 이름 충돌을 해결할 수 있도록 해준다.

<p>{{./name}} or {{this/name}} or {{this.name}}</p>
상기 예제는 각각 방식 모두 헬퍼에 있는 동일한 name을 이용하지 않고, 현재 컨텍스트의 name 필드를 이용하게 된다. 

Template comments with {{!-- --}} or {{! }}.

커멘트는 다음과 같이 사용할 수 있다. 
<div class="entry">
  {{!-- only output author name if an author exists --}}
  {{#if author}}
    <h1>{{firstName}} {{lastName}}</h1>
  {{/if}}
</div>
커멘트는 출력에 나타나지 않는다.

<div class="entry">
  {{! This comment will not be in the output }}
  <!-- This comment will be in the output -->
</div>
어떠한 커멘트든 반드시 }} 을 포함하거나 다른 핸들바스의 토큰들은 {{!-- --}}을 사용해야한다.

Helpers

Handlebars의 헬퍼는 템플릿의 어떠한 컨텍스트로 부터든 접근이 가능하다. 헬퍼는 Handlebars.registerHelper 메소드를 이용하여 등록 가능하다.
<div class="post">
  <h1>By {{fullName author}}</h1>
  <div class="body">{{body}}</div>
  <h1>Comments</h1>
  {{#each comments}}
  <h2>By {{fullName author}}</h2>
  <div class="body">{{body}}</div>
  {{/each}}
</div>
컨텍스트와 헬퍼 사용
var context = {
  author: {firstName: "Alan", lastName: "Johnson"},
  body: "I Love Handlebars",
  comments: [{
    author: {firstName: "Yehuda", lastName: "Katz"},
    body: "Me too!"
  }]
};
Handlebars.registerHelper('fullName', function(person) {
  return person.firstName + " " + person.lastName;
});
결과는 다음과 같다.
<div class="post">
  <h1>By Alan Johnson</h1>
  <div class="body">I Love Handlebars</div>
  <h1>Comments</h1>
  <h2>By Yehuda Katz</h2>
  <div class="body">Me Too!</div>
</div>
헬퍼들은 함수내에서 this를 통해서 현재 컨텍스트에 접근이 가능하다.
<ul>
  {{#each items}}
  <li>{{agree_button}}</li>
  {{/each}}
</ul>
컨텍스트와 헬퍼의 사용
var context = {
  items: [
    {name: "Handlebars", emotion: "love"},
    {name: "Mustache", emotion: "enjoy"},
    {name: "Ember", emotion: "want to learn"}
  ]
};
Handlebars.registerHelper('agree_button', function() {
  var emotion = Handlebars.escapeExpression(this.emotion),
      name = Handlebars.escapeExpression(this.name);
  return new Handlebars.SafeString(
    "<button>I agree. I " + emotion + " " + name + "</button>"
  );
});
결과는 다음과 같다.
<ul>
  <li><button>I agree. I love Handlebars</button></li>
  <li><button>I agree. I enjoy Mustache</button></li>
  <li><button>I agree. I want to learn Ember</button></li>
</ul> 
만약 헬퍼가 HTML을 반환하는 경우 escape처리 되지 않기를 원할수 있다. 이때에는 Handlebars.SafeString을 이용하자.

Literals

Helper는 또한 자신들에거 전달된 literal values 를 가질 수 있을 것이다. 이것이 파리미터 아규먼트이든지, 해시 아규먼트이든지. 지원된 리터럴은 numbers, strings, true, false, null 그리고 undefined 를 포함한다.

{{agree_button "My Text" class="my-class" visible=true counter=4}}

Partials

Handlebars partials는 공유 템플릿을 생성하여 코드를 재사용 할 수 있다. 이 템플릿을 렌더링은 다음과 같이 한다.
<div class="post">
  {{> userMessage tagName="h1" }}
  <h1>Comments</h1>
  {{#each comments}}
    {{> userMessage tagName="h2" }}
  {{/each}}
</div>
partial과 context를 시용하는 경우는 다음과 같다.
Handlebars.registerPartial('userMessage',
    '<{{tagName}}>By {{author.firstName}} {{author.lastName}}</{{tagName}}>'
    + '<div class="body">{{body}}</div>');
var context = {
  author: {firstName: "Alan", lastName: "Johnson"},
  body: "I Love Handlebars",
  comments: [{
    author: {firstName: "Yehuda", lastName: "Katz"},
    body: "Me too!"
  }]
};
결과는 다음과 같다.
<div class="post">
  <h1>By Alan Johnson</h1>
  <div class="body">I Love Handlebars</div>
  <h1>Comments</h1>
  <h2>By Yehuda Katz</h2>
  <div class="body">Me Too!</div>
</div>

1. handlebars 설치
















Share this

Related Posts

Previous
Next Post »