행복한 아빠

몇가지 Javascript template engine 본문

웹기술들

몇가지 Javascript template engine

행복한아빠 2009. 8. 5. 14:29
점점 웹 애플리케이션도 풍부하고 동적인 UI를 요구하는 경우가 늘어 AJAX 기술을 많이 사용한다.
AJAX를 이용하여 웹개발을 하다보니 점점 UI 렌더링을 서버의 JSP나 서블릿에서 처리하기 보다 Javascript에서 직접처리하는 빈도가 높아지고 있다.

간단한 AJAX 처리 구조는 다음과 같은 방법들이 있을 것이다.

1. 간단하고 쉬운 방법


Javascript에서 AJAX 통신을 하면 응답으로 UI의 일부로 붙일 수 있는 HTML 조각을 받는다. 이것을 UI 특정영역에 삽입하거나 교체한다.
구현하기 매우 쉬우나 서버 입장에서 순수한 데이터만 서비스하는게 아니라 UI 정보도 주어야 하기에 좋은 방법이라 말하기 어렵다. UI 정보도 서비스 할 경우 그 서비스가 다른 곳에서 사용되기 쉽지 않다는 단점도 있고.. 뭐 어쨌든 깔끔하지 않다.


2. 깔끔하지만 머리아픈 방법


서버에서는 순수한 서비스 정보(데이터)만 주고 Javascript에서 이 정보를 이용하여 UI의 DOM을 조작하여 화면을 갱신한다. API 중심이고 프로그래밍 중심이라 깔끔한 방법이고 확장성이 담보된다.
그러나 DOM 조작이 직관적인 방법이 아니고 머리아픈 작업이다. UI가 복잡해지면 (테이블 병합, 다단계 컬럼의 반복...) DOM 조작으로 시간을 모두 버리는 경우가 발생할 수도 있다.
뭐 추천하는 방법이긴하나 구현하기 어렵다.

3. 절충

서버에서는 순수한 서비스 정보만... Javascript에서 이 정보형태(JSON, XML)를 HTML로 변환한다.
이 경우 JSON이나 XML을 HTML으로 변환하는 작업이 필요한데 별 방법 없으면 열심히 루프 돌리거나 문자열 조작해서 변환한다.
그야말로 이 부분이 삽질이 될 수 있다.

4. Tempate Engine
모델과 뷰를 분리한다는 말을 많이 들어보았을 것이다. 즉 순수한 정보와 표현정보를 분리하고 이 둘을 합쳐 결과물을 만들어내는 것이다.
이에 관해 웹 애플리케이션에서 많이 사용하는 기술이 JSP나 FreeMarker, apache velocity등이 있는데 이러한 것들을 template engine이라고 한다.



5. 세 가지 Javascript template engine

위의 3번 방법을 쓸 경우 Javascript를 HTML 변환할 때 template engine을 사용하면 멋지지 않을까?
Google 神 에게 물어보고 다음과 같은 엔진을 찾았다.


"javascript template engine"으로 검색한 결과 1등으로 검색된 놈이다. 그래서 신뢰가 가고 열심히 테스트해 보았다.
이 놈은 jquery 기반으로 돌아가서 (Prototype, BooTools도 지원한단다) jquery.js 도 있어야 한다.

간단한 예제는 다음과 같다.
렌더링할 HTML
<div id="hello">
  Hello <span class="who">World</span>
</div>

Javascript 코드
$('#hello').autoRender({ "who": "Mary" })

이 뜻은 "hello" 아이디를 가진 DOM 트리 밑의 "who"라는 클래스를 가지 요소를 "Mary"로 교체하겠다는 뜻이다.
이 정도만 보면 굉장히 좋다는 것을 알 수 있다. 그러나 loop가 필요하거나 특히 중첩된 loop 그리고 한 번 변환한 후 다시 변환할 경우 사용하기가 까다롭다.
일반적인 template engine이 지원하는 문법도 아니라 약간의 학습곡선이 필요하다. 다뤄야 할 기술도 많은데 일관적이지 못한 사용방법은 개인적으로 좋아하지 않는다. 패스...


이 놈도 jquery 기반이다. (오우~ 막강 jquery) 해당 사이트 가면 첫 대문에 template 예제가 있다.
일반적인 template 문법이라 이해하기 어렵지 않으나 2009년 8월 현재 버전이 0.7.8 이다.
프레임워크 선택 시 중요한 것중 하나가 프로젝트의 성숙도이다. 대충 문서만 읽어보고 패스...


Google code 에서 진행하는 javascript template 엔진이다. 다른 JS 필요없이 20KB 정도의 template.js만 있으면 된다. 아래 예제는 위 사이트의 "JST(JavaScriptTemplates) 10분 소개"의 내용이다.

먼저 HTML에서 template.js를 로드하고...
 <html>
    <head>
      <script language="javascript" src="trimpath/template.js"></script>
      ...
    </head>
    ...
  </html>

다음, 테스트를 위한 구조적인 javascript 객체를 생성한다. 물론 이부분은 실제 AJAX 통신을 통해 가져올 수 있다.
  <script language="javascript">
    var data = {
        products : [ { name: "mac", desc: "computer",     
                       price: 1000, quantity: 100, alert:null },
                     { name: "ipod", desc: "music player", 
                       price:  200, quantity: 200, alert:"on sale now!" },
                     { name: "cinema display", desc: "screen",       
                       price:  800, quantity: 300, alert:"best deal!" } ],
        customer : { first: "John", last: "Public", level: "gold" }
    };
  </script>

다음은 데이터를 렌더링할 샘플 JST 템플릿이다. 템플릿은 HTML 페이지안에 숨겨진 <textarea>에 넣는다.
  <textarea id="cart_jst" style="display:none;">
    Hello ${customer.first} ${customer.last}.<br/>
    Your shopping cart has ${products.length} item(s):
    <table>
     <tr><td>Name</td><td>Description</td>
         <td>Price</td><td>Quantity & Alert</td></tr>
     {for p in products}
         <tr><td>${p.name|capitalize}</td><td>${p.desc}</td>
             <td>$${p.price}</td><td>${p.quantity} : ${p.alert|default:""|capitalize}</td>
             </tr>
     {forelse}
         <tr><td colspan="4">No products in your cart.</tr>
     {/for}
    </table>
    {if customer.level == "gold"}
      We love you!  Please check out our Gold Customer specials!
    {else}
      Become a Gold Customer by buying more stuff here.
    {/if}
  </textarea>

JST API를 이용하여 tempate 프로세싱을 해보자. (사실 아래에서 첫번째 줄이면 끝이다.)
  <script language="javascript">
    // 한줄로 프로세싱을 끝내는 방법 
    var result = TrimPath.processDOMTemplate("cart_jst", data);
    //  봐 바!  이게 다야  That's it
    // 이제 result 변수에 우리의 JST 렌더링 첫작품을 담고 있어.

    // 다른 방법으로는 명시적으로 템플릿을 파싱할 수도 있어...
    var myTemplateObj = TrimPath.parseDOMTemplate("cart_jst");
    // 이제부터는 파싱 비용이 들지 않지 (즉 계속 사용할 수 있다.)
    var result  = myTemplateObj.process(data);
    var result2 = myTemplateObj.process(differentData);
    // 마지막으로 위 결과를 innerHTML에 넣는 거지
    someOutputDiv.innerHTML = result;
    // document.write() 나 다른 것으로 처리할 수도 있겠지
  </script>

결과는 아래와 같을 것이다.
    Hello John Public.<br/>
    Your shopping cart has 3 item(s):
    <table>
     <tr><td>Name</td><td>Description</td>
         <td>Price</td><td>Quantity & Alert</td></tr>
         <tr><td>MAC</td><td>computer</td>
             <td>$1000</td><td>100 : </td>
             </tr>
         <tr><td>IPOD</td><td>music player</td>
             <td>$200</td><td>200 : ON SALE NOW!</td>
             </tr>
         <tr><td>CINEMA DISPLAY</td><td>screen</td>
             <td>$800</td><td>300 : BEST DEAL!</td>
             </tr>
    </table>
      We love you!  Please check out our Gold Customer specials!

덧붙여 템플릿을 HTML 페이지의 숨겨진 <textarea>에서 얻어왔는데, 바로 JavaScript String을 템플릿으로 사용할 수도 있다.
  <script language="javascript">
    var myStr = "Hello ${customer.first} ${customer.last}, Welcome back!";
    // process() method 사용은 쉽다.
    result = myStr.process(data);
    // 또는 middle-man variable을 사용하는것은 어떤가?
    result = "Hello ${customer.first} ${customer.last}, Welcome back!".process(data);
    // 결과는 똑같이 "Hello John Public, Welcome back!"일 것이다.
    result = "Hello " + customer.first + " " + customer.last + ", Welcome back!";
    // 파싱 비용을 줄이기 위해 한번만 파싱하는 방법을 쓸 수도 있다.
    var myTemplateObj = TrimPath.parseTemplate(myStr);
    var result  = myTemplateObj.process(data);
    var result2 = myTemplateObj.process(differentData);
  </script>  


일반적인 template 문법과 상당히 유사해서 FreeMarker나 velocity를 사용해본 사람이면 바로 쓸 수 있을 것이다. 따라서 PURE에서 이야기했던 문제점은 없고 어떠한 복잡한 템플릿도 쉽게 작성할 수 있다.

또한 템플릿에서 제공하는 문법 (if, else, foreach, ...) 뿐만 아니라 Macro등 유용한 기능들을 지원한다.
그리고 데이터 출력시 포맷팅(날짜, 금액-3자리마다 컴마)을 쉽게하기 위한 Modifier를 지원하는데 이게 참 유용한 기능이다.

적극 추천하는 javascript template engine이다.

끝...

'웹기술들' 카테고리의 다른 글

Cross domain JSON 원리  (4) 2009.12.09
Cross domain Ajax: 간략 요약  (0) 2009.12.08
몇가지 Javascript template engine  (5) 2009.08.05
SOAP이냐 REST이냐 - 표준이냐 간결함이냐  (6) 2009.05.28
Struts2 Sitemesh Freemaker  (0) 2009.05.21
Flex 차트와 Javascript 연결  (1) 2008.07.22
5 Comments
댓글쓰기 폼