9

I just started using Mustache and I like it so far, but this has me perplexed.

I am using the GitHub gist API to pull down my gists, and part of what I want to do is include the embedding functionality into my page. The problem is Mustache seems to not want to have anything to do with my dynamic script tag.

For example, this works fine:

<div class="gist-detail">
    {{id}} <!-- This produces a valid Gist ID -->
</div>

Additionally, this works perfect:

<div class="gist-detail">
    <script src='http://gist.github.com/1.js'></script> <!-- Produces the correct embed markup with Gist ID #1 -->
</div>    

If I try to pull these together, something goes terribly wrong:

<div class="gist-detail">
    <script src='http://gist.github.com/{{id}}.js'></script> <!-- Blows up! -->
</div>  

Chrome Inspector shows this:

GET https://gist.github.com/%7B%7Bid%7D%7D.js 404 (Not Found)

... which looks like to me something is weird with escapes or whatnot, so I switch over to the raw syntax:

<div class="gist-detail">
    <script src='http://gist.github.com/{{{id}}}.js'></script> <!-- Blows again! -->
</div>  

And I get the same result in Inspector:

GET https://gist.github.com/%7B%7B%7Bid%7D%7D%7D.js 404 (Not Found)

How do I get the correct values to embed in the script tag?

EDIT

I am injecting the template as follows (in document.ready:

function LoadGists() {
    var gistApi = "https://api.github.com/users/<myuser>/gists";

    $.getJSON(gistApi, function (data) {

        var html, template;
        template = $('#mustache_gist').html();

        html = Mustache.to_html(template, {gists: data}).replace(/^\s*/mg, '');
        $('.gist').html(html);
    });

}

The actually template is inside of a ruby partial, but it is wrapped in a div (not a script tag, is that a problem?) (that's hidden):

<div id="mustache_gist" style="display: none;">

    {{#gists}}
        <!-- see above -->
    {{/gists}}

</div>

I assume a div is ok rather than a script because in either case, I'm pulling the .html(). Is this a bad assumption?

Evan
  • 1,737
  • 1
  • 19
  • 32

3 Answers3

4

To avoid automatic escaping in Mustache use {{{token}}} instead of {{token}}.

oarevalo
  • 3,298
  • 1
  • 22
  • 19
0

It seems like your template is in HTML and trying to retrieve the template using html() results in a pre-URL-escaped template to be returned. Try placing your template inside a <script type="text/html"> tag instead.

When you embed your template inside an HTML element that excepts more HTML elements as children, it may get processed by the browser as HTML. Escaping may occur. By using a <script> tag with a non-script content type, you're basically telling the browser not to touch your template.

Ates Goral
  • 137,716
  • 26
  • 137
  • 190
-1

It looks like your script is getting requested before Mustache has a chance to update the src property. What you want to do is define the template in a way that it's not parsed as part of the DOM. A common approach is to define your template inside of a <textarea> tag. This will preserve formatting and prevent character escaping.

<textarea id="gist-detail-template" style="display:none">
  <script src='http://gist.github.com/{{id}}.js'></script>
</textarea>

Now, to instantiate the template:

var template = $('#gist-detail-template').val();
var html = Mustache.to_html(template, yourTemplateData);

Here's an official example: http://mustache.github.com/#demo

Amit
  • 738
  • 5
  • 8
  • I switched my `div` template for a `textarea` and retrieved the template using `template = $('#mustache_gist').val();` - this cleared the inspector error but the script tag never renders, any idea? – Evan Jan 29 '12 at 06:33
  • It's possibly the way you're appending the html to the DOM. I'd try `$('body').append(html)`. Then inspect the body to make sure the tag was actually appended to it. – Amit Jan 29 '12 at 06:39