Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Example of Closure Templates compiling to Incremental DOM instructions

How a template for some sort of post may be translated to javascript. The following examples use the syntax from Closure templates, but any templating language can be used.

Starting with the content of a post, we might have a template like the following:

{namespace some.namespace}


/**
 * @param postInfo The data for the post
 */
{template .postContent}
  <div>{$postInfo.title}</div>
  
  <div>
    <img src="{$postInfo.author.image}">
    <span>{$postInfo.text}</span>
  </div>
{/template}

Which might translate to:

function some.namespace.postContent(data) {
  var postInfo = data.postInfo.
  elementOpen('div', null);
    text(postInfo.title);
  elementClose('div');
  elementOpen('div', null);
    elementVoid('img', null, null,
      'src', postInfo.author.image);
    elementOpen('span', null);
      text(postInfo.text);
    elementClose('span');
  elementClose('div');
}

Now to create a card template that we can put our post inside:

/**
 * @param classes Extra classes for the card
 * @param content The card's content
 */
{template .card}
  <div class="card{if $classes} ${classes}{/if}">
    {$content}
  </div>
{/template}

Which might translate to:

function some.namespace.card(data) {
  var classes = data.classes;
  var content = data.content;
  elementOpen('div', null, null,
      'class', 'card' + classes ? ' ' + classes : '');
    content();
  elementClose('div');
}

Before passing our content to the card, lets add a check to see if the post is loading, and if so, render a spinner instead:

/**
 * @param postInfo The data for the post
 */
{template .post}
  {call some.namespace.card}
    {param classes kind="text"}supercard{/param}
    {param content kind="html"}
      {if $postInfo.isLoading}
        {call some.namespace.spinner /}
      {else}
        {call .postContent data="all" /}
      {/if}
    {/param}
  {/call}
{/template}

Which might translate to:

function some.namespace.post(data) {
  some.namespace.card({
    classes: 'supercard',
    content: function() {
      if (data.isLoading) {
        some.namespace.spinner();
      } else {
        postContent(data);
      }
    }
  })
}

Finally, lets render an array of posts:

/**
 * @param postInfoArray An array of postInfo
 */
{template .postList}
  <div>
    {foreach $postInfo in $postInfoArray}
      {call .post}
        {param postInfo: $postInfo /}
      {/call}
    {/foreach}
  </div>
{/template}

Which might translate to:

function some.namespace.postList(data) {
  var postInfoArray = data.postInfoArray;
  elementOpen('div', null);
    for (var i = 0; i < postInfoArray.length; i++) {
      var postInfo = postInfoArray[i];
      some.namespace.post({
        postInfo: postInfo      
      });
    }
  elementClose('div');
}
@MadebyAe

This comment has been minimized.

Copy link

commented Jul 10, 2015

Nice!

@syzer

This comment has been minimized.

Copy link

commented Jul 12, 2015

👍

@miniflycn

This comment has been minimized.

Copy link

commented Jul 27, 2015

awesome!!

@SerkanSipahi

This comment has been minimized.

Copy link

commented Sep 6, 2015

incredible :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.