简体   繁体   中英

Escape Mustache variable containing apostrophe for JavaScript

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 eg 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".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM