티스토리 뷰

Handlebars.js

pilot376 2013. 7. 25. 14:33

Handlebars는 유저가 효과적으로 semantic template을 만들 수 있는 필수 기능을 제공한다.


Getting Started

<script> 태그 내에 handlebars 템플릿을 작성한다. 템플릿이 위치하는 <script> 태그에는 "type="text/x-handlebars-template" 속성을 추가한다. handlebars 템플릿은 보통의 HTML 문법과 같고 handlebars 정규식이 포함되어 있다. handlebars 정규식은 "{{", "}}" 사이에 위치한다.

<script id="entry-template" type="text/x-handlebars-template">
    <div class="entry">
        <h1>{{title}}</h1>
        <div class="body">
            {{body}}
        </div>
    </div>
</script>

작성된 handlebars 템플릿은 Handlebars.compile을 이용하여 컴파일할 수 있다. 컴파일한 후 context를 파라미터로 전달하여 결과물을 얻을 수 있다. context의 key 값에 해당하는 handlebars 정규식 위치에 context의 value 값을 반환한다.

<script>
    var source = $("#entry-template").html(); // ID 값으로 템플릿을 가져옴
    var template = Handlebars.compile(source); // Handlebars.compile을 이용하여 컴파일
 
    var context = {title: "My New Post", body: "This is my first post!"}; 
    var html = template(context); // context를 파라미터로 전달
</script>

"console.log(html);"으로 확인해보면 아래의 결과를 얻을 수 있다.

<div class="entry">
    <h1>My New Post</h1>
    <div class="body">
        This is my first post!
    </div>
</div>

"{{정규식}}"을 사용하면 escape 된 HTML 문자를 받아 온다. 만약 문자가 escape 되는 것을 원하지 않는다면, 중괄호 세 개를 써서 "{{{정규식}}}" 형식으로 작성한다. escape 되지 않는 또 다른 방법은 "Handlebars.SafeString"을 사용하는 것이다. "Handlebars.SafeString"은 헬퍼 함수를 작성하여 사용할 수 있으며(헬퍼 사용법은 아래에), 중괄호 세 개를 쓰지 않아도 escape 되지 않는다.

<script id="entry-template" type="text/x-handlebars-template">
    <div class="entry">
 
        {{! 중괄호 세 개 사용 }}
        <div class="escape">
            {{escape}}
            {{{escape}}}
        </div>
 
        {{! Handlebars.SafeString 사용 }}
        <div class="safe-string">
            {{safe escape}}
            {{{safe escape}}}
        </div>
 
    </div>
</script>
 
<script>
    var source   = $("#entry-template").html();
    var template = Handlebars.compile(source);
    var context = {
        escape : "<p>This is a post about &lt;p&gt; tags</p>"
    };
    
    // 헬퍼 등록
    Handlebars.registerHelper('safe', function(text) {
        return new Handlebars.SafeString(text);
    });
   
    var html = template(context);
</script>

"console.log(html);"으로 확인해보면 아래의 결과를 얻을 수 있다.

<div class="entry">
    
    {{! 중괄호 세 개 사용 }}
    <div class="escape">
        &lt;p&gt;This is a post about &amp;lt;p&amp;gt; tags&lt;/p&gt;
        <p>This is a post about &lt;p&gt; tags</p>
    </div>
 
    {{! Handlebars.SafeString 사용 }}
    <div class="safe-string">
        <p>This is a post about &lt;p&gt; tags</p>
        <p>This is a post about &lt;p&gt; tags</p>
    </div>
 
</div>

예제 다운로드 handlebars-getting started.zip


Block Expressions

블럭 표현식은 현재의 context를 특정 부분으로 변경하거나 반복문, 조건문 등 다양한 기능을 할 수 있는 헬퍼 함수를 정의하여 사용할 수 있도록 해준다. 블럭 표현식은 "#"으로 시작하고 "/"으로 닫는다.

// template
<div class="content">
    {{#article}} {{! context 중에서 article 부분을 블럭 표현식으로 사용한다. }}
        <h2>{{title}}</h2> {{! article 아래에 title을 출력한다. }}
    {{/article}}
</div>
 
// context
var context = {
    site: {
        title: 'AwesomeBlog',
        url: 'http://blog.example.com'
    },
    article: {
        id: 1,
        title: 'My blog is awesome'
    }
};
 
//output
<div class="content">
    <h2>My blog is awesome</h2>
</div>

빌트인 헬퍼인 each를 사용한 예제

// template
<ul>
{{#each device}} {{! each 헬퍼에 device 배열을 파라미터로 전달한다. }}
    <li>{{name}}</li>
{{/each}}
</ul>
 
// context
var context = {
    device: [
        {name: 'iPhone'},
        {name: 'Android'},
        {name: 'Windows Phone'}
    ]
};
 
//output
<ul>
    <li>iPhone</li>
    <li>Android</li>
    <li>Windows Phone</li>
</ul>


Handlebars Paths

"."은 "template(context)" 함수에 던져진 context 파라미터 자기 자신을 가리킨다. "this"로도 사용할 수 있다.

/********** context가 자기 자신을 가리키기 때문에 아래와 같이 사용할 수 있다. **********/ // template <div class="entry"> <h1>{{./title}}</h1> <div class="body"> {{this/body}}
</div> </div> // context var context = { title: "My New Post", body: "This is my first post!" }; /********** 블럭 표현식을 사용한 경우 자기 자신은 지정된 블럭 context가 된다. **********/ // template <div class="content"> {{#article}} <h2>{{this/title}}</h2> {{! "this"는 article을 가리키기 때문에 article 하위에 title이 출력됨 }} {{/article}} </div> // context var context = { site: { title: 'AwesomeBlog', url: 'http://blog.example.com' }, article: { id: 1, title: 'My blog is awesome' } };

"."은 자기 자신을 가리키기도 하지만 자식 context에 접근할 수 있는 연결고리가 되기도 한다. "{{parent.child}}"와 같은 형태로 사용할 수 있다. "{{parent/child}}"도 같은 결과를 출력한다.

// template
<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!"
};

"../"을 이용하여 부모 context에 접근할 수 있다.

// template
{{#article}}
    {{! "../"는 article의 부모인 context를 가리키고, context 아래에 "site.url"을 출력한다. }}
    <h2><a href="{{../site.url}}/article/{{id}}">{{title}}</a></h2> 
{{/article}}
 
// context
var context = {
    site: {
        title: 'AwesomeBlog',
        url: 'http://blog.example.com'
    },
    article: {
        id: 1,
        title: 'My blog is awesome'
    }
};


Template comments

 template에서 "{{! }}"를 이용하여 주석을 달 수 있다.

<div class="entry">
    {{! only output this author names if an author exists }}
    {{#if author}}
        <h1>{{firstName}} {{lastName}}</h1>
    {{/if}}
</div>


Helpers

Handlebars.registerHelper 메소드를 이용하여 헬퍼를 등록할 수 있다. 헬퍼를 사용하여 템플릿의 context에 다양한 방법으로 접근할 수 있다.

//template
<h1>{{fullName author}}</h1> 
{{! 헬퍼를 생성 {{헬퍼이름 컨텍스트}} 컨텍스트는 헬퍼 함수의 파라미터로 전달된다. }}
 
//context
var context = {
    author: {firstName: "Alan", lastName: "Johnson"},
    body: "I Love Handlebars",
    comments: [{
        author: {firstName: "Yehuda", lastName: "Katz"},
        body: "Me too!"
    }]
};
 
// helper
Handlebars.registerHelper('fullName', function(person) {
    return person.firstName + " " + person.lastName;
});
 
// output
<h1>Alan Johnson</h1>

블럭 헬퍼 등록

// template
{{#list people}}  {{! 블럭 헬퍼를 생성 {{#블럭헬퍼이름 블럭컨텍스트}} }}
    {{firstName}} {{lastName}}
{{/list}}
 
// context
var context = {
  people: [
    {firstName: "Yehuda", lastName: "Katz"},
    {firstName: "Carl", lastName: "Lerche"},
    {firstName: "Alan", lastName: "Johnson"}
  ]
};
 
// helper
Handlebars.registerHelper('list', function(items, options) { 
    // 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>";
});
 
// output
<ul>
    <li>Yehuda Katz</li>
    <li>Carl Lerche</li>
    <li>Alan Johnson</li>
</ul>


Built-in Helpers


the "with" Block Helper

with 헬퍼는 context를 바꾸는 역할을 한다.

// template
<div class="entry">
    <h1>{{title}}</h1>
 
    {{#with author}} {{! 이 블럭에서는 author가 context가 된다. 네임스페이스 같은 역할을 한다. }}
    <h2>By {{firstName}} {{lastName}}</h2>
    {{/with}}
</div>
 
// context
var context = {
    title: "My first post!",
    author: {
        firstName: "Charles",
        lastName: "Jolley"
    }
};
 
// output
<div class="entry">
    <h1>My first post!</h1>
    <h2>By Charles Jolley</h2>
</div>


the "each" block helper

블럭 안에서 반복문을 실행한다.

// template
<ul class="people_list">
    {{#each people}}
    <li>{{this}}</li>
    {{/each}}
</ul>
 
// context
var context = {
    people: [
        "Yehuda Katz",
        "Alan Johnson",
        "Charles Jolley"
    ]
};
 
// output
<ul class="people_list">
    <li>Yehuda Katz</li>
    <li>Alan Johnson</li>
    <li>Charles Jolley</li>
</ul>


the "if" block helper

블럭 안에서 조건문을 실행한다.

<div class="entry">
    {{#if author}}
    <h1>{{firstName}} {{lastName}}</h1>
    {{/if}}
</div>
 
 
// author 객체가 존재하지 않거나, 빈 객체일 경우 아래의 결과를 출력
<div class="entry">
</div>
 
// else를 사용할 수 있음.
<div class="entry">
    {{#if author}}
    <h1>{{firstName}} {{lastName}}</h1>
    {{else}}
    <h1>Unknown Author</h1>
    {{/if}}
</div>


the "unless" block helper

if와 반대되는 조건문을 실행한다.

<div class="entry">
    {{#unless license}}
    <h3 class="warning">WARNING: This entry does not have a license!</h3>
    {{/unless}}
</div>


참조


댓글