最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Escape Mustache variable containing apostrophe for JavaScript - Stack Overflow

programmeradmin3浏览0评论

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.

I have a variable ({{title}}) which contains an apostrophe. Mustache escapes this as &#39;.

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.

Share Improve this question asked May 14, 2014 at 18:42 Jason McCrearyJason McCreary 73k23 gold badges138 silver badges177 bronze badges 5
  • Interesting! I suppose this is not possible with Mustache. Should not be much of a problem with Handlebars (Handlebars.registerHelper)... – hgoebl Commented May 14, 2014 at 20:30
  • @hgoebl, the solution does not have to be Mustache. – Jason McCreary Commented May 14, 2014 at 20:54
  • Then you should have a look at Handlebars. It's a superset of Mustache and can be extended very easily. You would have to create and register a helper-function like escapeJs and in your template use it like {{escapeJS title}}. If I find time I'll fork your fiddle... – hgoebl Commented May 15, 2014 at 6:57
  • I know this is only a dumb workaround (replacing the apostrophe problem with another character), but a quick & dirty solution would be: "<a href='javascript:confirm(\"{{title}}\");'>{{title}}</a>". – hgoebl Commented May 15, 2014 at 7:13
  • @hgoebl, I agree that would work. I was asking if JavaScript or Mustache had something I was missing. – Jason McCreary Commented May 15, 2014 at 13:37
Add a ment  | 

2 Answers 2

Reset to default 8

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>

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.pile(
    "<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".

发布评论

评论列表(0)

  1. 暂无评论