{"id":1717,"date":"2010-06-30T23:58:17","date_gmt":"2010-06-30T23:58:17","guid":{"rendered":"http:\/\/justthesam.com\/2010\/06\/grails-gsp-html-escaping-confusion\/"},"modified":"2010-06-30T23:58:17","modified_gmt":"2010-06-30T23:58:17","slug":"grails-gsp-html-escaping-confusion","status":"publish","type":"post","link":"https:\/\/justthesam.com\/?p=1717","title":{"rendered":"Grails GSP HTML escaping confusion"},"content":{"rendered":"<p>I&#39;m currently getting to grips with Groovy and Grails. One major frustration that took a while to figure out was HTML escaping in GSP pages. Here&#39;s the simple lowdown, including at the end the important bit that I had struggled to realise, which is how to <strong><em>not<\/em><\/strong> escape specific strings when global HTML escaping is turned on.<\/p>\n<h3>Manual escaping<\/h3>\n<p>Out of the box (i.e. with a vanilla Grails app with default config) you need to explicitly escape any dangerous strings with the encodeAsHTML() function that Grails makes available on all Strings: ${dangerString.encodeAsHTML()}. This is a bit verbose, but at least it&#39;s very clear, and because it&#39;s just a method on String it&#39;s available everywhere in your app, not just in GSPs.<\/p>\n<h3>Auto-escaping with default codec<\/h3>\n<p>If you modify Config.groovy to contain&#0160;grails.views.default.codec = &quot;html&quot; (which is there by default and set to &quot;none&quot;) then it automatically calls encodeAsHTML() for you whenever you use ${} in GSPs. This is clearly quite a handy option and a much safer way of configuring things as it lessens the likelihood of slipping up and leaving a hole in your app.<\/p>\n<h3>Overriding auto-escaping per item<\/h3>\n<p>So far this is all exactly as per <a href=\"http:\/\/grails.org\/doc\/latest\/guide\/single.html#11.2%20Encoding%20and%20Decoding%20Objects\" target=\"_blank\" rel=\"noopener\">the Grails docs<\/a> (which go into much more detail on codecs and what&#39;s really going on, including creating your own) but the crucial bit they fail to mention is what to do if you&#39;ve turned on the global html codec, but have situations where you don&#39;t want escaping. The answer is to simply use the alternative JSP style interpolation syntax &lt;%=mySafeHTMLString%&gt; since the codec is only applied to ${}.<\/p>\n<h3>Overriding auto-escaping per page<\/h3>\n<p>You can also set the codec on a per-page basis, overriding that set in Config.groovy, with&#0160;&lt;%@page defaultCodec=&quot;html&quot; %&gt; or&#0160;&lt;%@page defaultCodec=&quot;none&quot; %&gt; as appropriate.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#39;m currently getting to grips with Groovy and Grails. One major frustration that took a while to figure out was HTML escaping in GSP pages. Here&#39;s the simple lowdown, including at the end the important bit that I had struggled to realise, which is how to not escape specific strings when global HTML escaping is [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22,33],"tags":[],"class_list":["post-1717","post","type-post","status-publish","format-standard","hentry","category-programming","category-webtech"],"_links":{"self":[{"href":"https:\/\/justthesam.com\/index.php?rest_route=\/wp\/v2\/posts\/1717","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/justthesam.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/justthesam.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/justthesam.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/justthesam.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1717"}],"version-history":[{"count":0,"href":"https:\/\/justthesam.com\/index.php?rest_route=\/wp\/v2\/posts\/1717\/revisions"}],"wp:attachment":[{"href":"https:\/\/justthesam.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1717"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/justthesam.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1717"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/justthesam.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1717"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}