db2791
db2791

Reputation: 1110

Handlebars example not working

In my .hbs delivered by my node server:

<script src="/javascripts/handlebars.min-latest.js"></script>

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

In my client-side javascript file:

var source   = $("#entry-template").html();
var template = Handlebars.compile(source);
var context = {title: "My New Post", body: "This is my first post!"};
var html    = template(context);
console.log(html);

My output:

<div class="entry">
    <h3></h3>
    <div class="body">

    </div>
</div>

Basically, even with the simplest example on their frontpage, it isn't working. Is it because I'm using handlebars on the front and back end? If so, how can I go around that?

Upvotes: 3

Views: 9799

Answers (4)

eballeste
eballeste

Reputation: 809

searching for issues when trying to use handlebars with shopify themes?

You are definitely experiencing liquid parsing the variables and serving empty strings to the client. The liquid solution is to enclose your handlebar template within raw & endraw tags.

{% raw %}
<script id="cartItemTemplate" type="text/x-handlebars-template">
   ...
</script>
{% endraw %}

Upvotes: 1

Medi
Medi

Reputation: 1036

Client-side templates when using Handlebars on the server

If you’re using Handlebars on the client and the server, you’ll run into this issue where the client-side templates will be parsed by the view engine on the server. For example, you may have a file like this:

 <h1>My Page Title</h1>
 <!-- This template should be transformed into HTML by the server -->
 <div id="photoList" class="pure-g">
    {{#each photos}}
        <div class="photo pure-u-1-12" data-photo-id="{{id}}">
            <img class="pure-u-1" src="{{src}}">
        </div>
    {{/each}}
 </div>

<!-- This template should not be touched. It's for the client -->
 <script type="text/x-handlebars" id="lightbox-template">
    <img class="lightbox-image" src="{{large}}">
    <div class="lightbox-meta">
        <a class="pure-button lightbox-link" href="{{url}}">View on Flickr</a>
        <button class="pure-button lightbox-link lightbox-hide">Hide</button>
    </div>
 </script>

When you view this on the browser, the tags ({{..}}) within will be parsed out. You’ll get something like this, which is useless:

<!-- I can't use this template on the client anymore!! -->
<script type="text/x-handlebars" id="lightbox-template">
  <img class="lightbox-image" src="">
<div class="lightbox-meta">
    <a class="pure-button lightbox-link" href="">View on Flickr</a>
    <button class="pure-button lightbox-link lightbox-hide">Hide</button>
 </div>
</script>

Fortunately, the fix for this is very simple, albeit not documented anywhere. Just add a \ in front of all the opening tags ({{). The \ will be parsed out during the compilation step, and you’ll have a perfectly usable template on the client.

<!-- Add a \ before the handlebars -->
<script type="text/x-handlebars" id="lightbox-template">
  <img class="lightbox-image" src="\{{large}}">
  <div class="lightbox-meta">
     <a class="pure-button lightbox-link" href="\{{url}}">View on Flickr</a>
     <button class="pure-button lightbox-link lightbox-hide">Hide</button>
  </div>
</script>

Source: link

Upvotes: 1

Zlati Iliev
Zlati Iliev

Reputation: 41

If you use Handlebars for both backend and frontend there is an easy fix. Just escape the variables which are meant for your frontend parser by adding a \ in foront of them like so \{{myVar}}, and leave the variables which are to be parsed by the server to {{myServerVar}}.

<script type="text/x-handlebars-template" id="my-row-template"> ​
    <tr>
        <td></td>
        <td>\{{fieldName}}</td>
    </tr>
</script>

Upvotes: 4

Nikolay Ermakov
Nikolay Ermakov

Reputation: 5061

Add $('body').append(html); to you script:

var source   = $("#entry-template").html();
var template = Handlebars.compile(source);
var context = {title: "My New Post", body: "This is my first post!"};
var html    = template(context);

$('body').append(html);

Fiddle Demo

Upvotes: 0

Related Questions