1

We have a FTL that has -

<a href='javascript:func("${event.title}");'>Link</a>

When the value has an apostrophe, like Norman'S Birthday - it breaks.

We used js_string to fix it -

<a href="javascript:func('${event.title?js_string}');">Link</a>

But we also had to change the double quotes around $expression to single quotes - this does Not work with double quotes.

Question -

Is there a way to fix this with the original double quotes around the $expression ?

Something like -

<a href='javascript:func("${event.title?js_string}");'>Link</a>

Note the above does not work.

jforex78
  • 315
  • 2
  • 11
  • Possible duplicate of [What is the correct way to support apostrophes in javascript when building up html?](https://stackoverflow.com/questions/24154267/what-is-the-correct-way-to-support-apostrophes-in-javascript-when-building-up-ht) – Obsidian Age Mar 18 '18 at 23:26
  • 1
    @ObsidianAge Not a duplicate, as OP needs to do this with FreeMarker. – ddekany Mar 19 '18 at 00:07
  • Is there a way to tell FTL at entire file-level to take care of escaping? Like a global-macro? – jforex78 Mar 19 '18 at 18:39
  • @jforex78 You can configure FreeMarker to use HTML auto-escaping on all `*.ftlh` files, or even on all files. But I believe the material lined from my answer covers that. If you some complex case, like only templates inside certain directories should be auto-escaped, then see https://freemarker.apache.org/docs/pgui_config_templateconfigurations.html. – ddekany Mar 24 '18 at 08:11

3 Answers3

2

You need two kind of escaping applied here: JavaScript string escaping and HTML escaping. You need both, as the two formats are independent, and the JavaScript is embedded into HTML.

How to do that... the primitive way is event.title?js_string?html, but it's easy to forget to add that ?html, so don't do that. Instead, use auto-escaping (see https://freemarker.apache.org/docs/dgui_quickstart_template.html#dgui_quickstart_template_autoescaping). If you can't use that form of auto-escaping for some reason (like you are using some old FreeMarker version and aren't allowed to upgrade), put the whole template into <#escape x as x?html>...</#escape>. In both cases, you can just write ${event.title?js_string}, and it will just work.

However, if you are using #escape, ensure that the incompatible_improvements setting (see https://freemarker.apache.org/docs/pgui_config_incompatible_improvements.html) is at least 2.3.20, or else ?html doesn't escape '.

ddekany
  • 29,656
  • 4
  • 57
  • 64
0

Modify the value of event.title so that single quotes are replaces with &apos; and double quotes are replaces with &quot;, then you won't have to worry at all about which kind of quotes you use for the rest of it.

kshetline
  • 12,547
  • 4
  • 37
  • 73
  • Yes thats a good alternative. Except - we have to replace all special characters one by one - like `apos`, `quot`, etc. We need something like `js_string` that takes care of escaping in a general manner. Thanks. – jforex78 Mar 19 '18 at 17:57
0

?js_string should be outside curly brackets {}. Now you should use double quotes " " around href value, if you wanna handle single quotes ' ' inside the string and vice versa. Single and double quote can not be used in same string, so either of them needs to be replaced to other.

solution:
<a href="javascript:func('${event.title!?js_string}');">Link</a>

Same expression can be used in JavaScript to handle special characters