Template 과 Collection 기능만 알면 meteor의 기능을 50% 활용할 수 있다고 생각합니다. 실제 meteor example application 을 보더라도 Template와 Collection 사용부분이 많은 영역을 차지합니다. 그럼 시작해보겠습니다. 참고로 이글은 template engine에 대해서 알고 있다는 전제입니다.

Meteor는 client 에서 startup (Domready) 하기전에 HTML 전체를 precompile 하여 <tempalte> Element를 정규표현식으로 찾아내어 파싱합니다.
/usr/local/meteor/packages/templating/html_scanner.js 파일 참조하세요.
파싱후 global object인 Template 객체를 사용할 수 있게 됩니다.
여기서 중요한것이 파싱된 Template Element 정보들이 Template Object에 모두 할당됩니다.
참고로 ICanHaz Template Engine 은 이와 동일한 구성을 가지고 있습니다.
meteor 에서 사용하는 Template Engine 종류는 Handlebars 를 사용합니다. 기존에 mustache를 사용했던 분이면 이것이 익숙할 것입니다.
Block Helpers (if, each …) 기능은 여기서 설명하지 않고, handlebar 문서를 참고하세요.html 파일을 생성합니다.name Attribute 를 가진 <template name="foo"> ~ </template> Element 를 삽입합니다.HTML 구문을 삽입합니다.HTML에 아래와 같이 정의하였다고 가정합니다.
<template name="Name">
<div class="foo">{{bar}}</div>
</template>
Template API 는 현재 meteor doc에 정확히 정의가 안되어 있으나, 사용하시기에는 어려움이 없을것입니다. 하나하나 짚어나가겠습니다.
Template.TName 말그대로 <template name="TName">~</template> 해당 Element의 name을 지정하여 접근하고 치환할 수 있습니다.
Template.TName(Object);
치환할 대상을 지정한 key값에 대응하는 object를 정의합니다.
Template.TName({bar: "baz"});
=> "<div class="foo">baz</div>"
Template.TName 말그대로 <template name="TName">~</template> 해당 Element의 name을 지정하여 접근하고 template 안에서 지정한 {{ ~ }} 치환자에 Data (Collection, Sesssion)를 bind 할 수 있습니다.
Template.TName.치환자_키명 = Function;
HTML 에 아래와 같이 지정하고,
<template name="leaderboard">
<div>
{{#each players}}
{{/each}}
</div>
</template>
JS 에 아래와 같이 정의합니다.
//
// template name이 leaderboard 에 접근하고,
// players 치환자에 function을 지정하며
// 그 function의 return 값은 Collection cursor 입니다.
//
Template.leaderboard.players = function () {
return Players.find({}, {sort: {score: -1, name: 1}});
};
Template.TName 말그대로 <template name="TName">~</template> 해당 Element의 name을 지정하여 접근하고, template 안에서 지정한 {{ ~ }} 치환자에 Event (click …)를 bind 할 수 있습니다.
Template.Name.events = EventObject;
EventObject 지정방법은 이전 편에서도 많이 알려드렸고, 정확한 문서는 이곳을 참조하시기 바랍니다.
HTML 에 아래와 같이 지정합니다. {{> player}} 같은 부분이 추가되었는데, partial 이라는 치환자입니다. 이것의 기능은 다른 template Element를 불러올 수 있는 기능입니다. include 라고 생각하시면 됩니다.
<template name="leaderboard">
<div>
{{#each players}}
{{> player}}
{{/each}}
</div>
</template>
<!--
partial에 해당하는 template
위 예제에서 data bind 하였는데, data 의 키값은 name, score로 이루어져 있습니다.
-->
<template name="player">
<div>
<span class="name">{{name}}</span>
<span class="score">{{score}}</span>
</div>
</template>
JS 에 아래와 같이 정의합니다.
//
// player template 에 접근하여 events 를 선언합니다.
//
Template.player.events = {
'click': function () {
console.log('event delegation 적용되었다.')
}
};
이 전편을 읽으신 분들은 Meteor.ui.render의 기능이 Template Element와 Template Object 으로 동일한 효과를 낼 수 있다는것을 알아채실 것입니다. 즉, 다이나믹하게 UI를 컨트롤 하고 싶을때는 Meteor.ui부분을 보면 되고, 정적인 구조를 만들고 싶을때는 이번편을 참고하시면 됩니다.
//
// 이전편에 설명했듯이
// Meteor.ui.render 의 반환값은 DocumentFragment 라는것을 잊지 마세요.
//
var frag = Meteor.ui.render(function () {
//
// hello name을 가진 Template 에
// first, last 키값을 가진 치환자에 값을 대입한 후
// render에 반환합니다.
//
return Template.hello({first: "Alyssa", last: "Hacker"});
});
//
// forecast name을 가진 Template 를 선언합니다.
//
<template name="forecast">
//
// prediction 치환자를 선언합니다.
//
<div>It'll be {{prediction}} tonight</div>
</template>
//
// nested 접근합니다.
// forecast Template에 접근하고,
// prediction 치환자에 Data 를 bind 합니다.
// 여기서 Data 는 Session 이네요.
//
Template.forecast.prediction = function () {
//
// weather 세션키값을 가져옵니다.
//
return Session.get("weather");
};
firebug 에 아래와 같이 바로 브라우져에서 확인할 수 있도록 실행해봅니다.
일단 weather 세션키값을 cloudy 라고 선언합니다.
> Session.set("weather", "cloudy");
forecast name을 가진 Template를 Meteor.ui.render 에게 넘기고, 반환되는 DocumentFragment 를 appendChild에거 넘깁니다. 화면에 표시되갰죠.
> document.body.appendChild(Meteor.ui.render(Template.forecast));
//
// 아래와 같이 보일것입니다.
//
In DOM: <div>It'll be cloudy tonight</div>
그럼, Bind된 Data가 reactivity되는 모습을 확인해보겠습니다.
> Session.set("weather", "cool and dry");
Data를 변경하자마자 아래와 같이 변경된 값으로 반영됩니다.
In DOM: <div>It'll be cool and dry tonight</div>
이게 전부입니다. 굉장히 심플하고 사용하기 쉽고, 여기다가 Mongodb에 저장된 Data까지 reactivity하게 적용되니 굉장히 융통성있는 개발을 할 수 있을것입니다. 그럼 이것으로 줄이겠습니다. 감사합니다.