I have a variable ({{title}}
) which contains an apostrophe. Mustache escapes this as '
.
However, the following template results in a JavaScript error (Expected token ')'
):
<a href="javascript:confirm('{{title}}?');">{{title}}</a>
After Mustache rendering, the syntax error is clear ('Joe's Lame?'
):
<a href="javascript:confirm('Joe's Lame?');">Joe's Lame</a>
I am still learning Mustache and while this example is contrived, what is the proper way to escape variables in these situations.
The fiddle for reference.
So if it doesn't have to be Mustache, you can use a superset of Mustache called Handlebars.
First register a Handlebars helper:
Handlebars.registerHelper('escapeJs', function(str) {
return str.replace(/[\'\"\\\/]/gm, function (c) {
return '\\' + c;
});
});
And you call your helper like this {{escapeJs title}}
:
var view = {
title: "Joe's Lame\"\\/€"
};
var template = Handlebars.compile(
"<a href=\"javascript:confirm('{{escapeJs title}}');\">{{title}}</a>");
var output = template(view);
View it live in this fiddle.
Mustache is really cool and it's available in almost any programming language. Handlebars is awesome and is used e.g. in Backbone Thorax and assemble, a powerful static web-site generator.
Edit: Alternative Solution
When using ECMAScript 5 (and with shim/shiv/polyfills that should be working with IE8 as well), one could prepare the view-object for Mustache in the following way. I admit, that this is not a very handy solution, but when producing JavaScript output is rare, it might be acceptable IMO.
function escapeJs (str) {
return str.replace(/[\'\"\\\/]/gm, function (c) {
return '\\' + c;
});
}
var view = {
title: "Joe's Lame"
};
Object.defineProperty(view, 'titleJsEnc', {
enumerable: false,
get: function () { return escapeJs(this.title); }
});
var output = Mustache.render(
"<a href=\"javascript:confirm('{{titleJsEnc}}');\">{{title}}</a>", view);
Defining a new property (via Object.defineProperty) does the trick. One could write a generic object decorator which defines a getter for each real property returning the escaped string value.
Here is the fiddle
Edit: Alternative: Wait for a new version of Mustache
Once this pull-request is merged and a new version of Mustache is published, this problem should be solved in a "Mustache native way".
P/S: I know this is an old post, just in case someone find it useful. Like myself, I found your post too before I realized about the triple brackets solution.
In Mustache, just use the triple brackets, no need to be so headache:
{{{title}}}
But for your case, I don't think by simply escaping the single quote is enough. You should also reverse your single and double quotes like this:
<a href='javascript:confirm("{{{title}}}?");'>{{{title}}}</a>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With