Search code examples
grails

How to correctly concatenate two message properties in Grails?


The same message property (encoded as HTML) on one input field is rendered correctly while it (also encoded as HTML) displays the HTML tags in another input field. These occur in the GSP view.

I'd like to concatenate the message properties to avoid violating the DRY principle.

Input 1

<input type="text" class="freeform search-input" title="${g.message(code:"registration.classSearch.field.courseNumberLevels.placeholder.tooltip", encodeAs: "HTML")}">

Input 2 The false branch of the ternary operator is where I'm seeing the issue. I didn't strip out the ternary just in case it might be part of the problem.

<input title="${config.config.contains('keyword')? g.message(code:"registration.classSearch.field.keywordinputbox.placeholder.tooltip", encodeAs: "HTML"):g.message(code:"registration.classSearch.field.inputbox.placeholder.tooltip", encodeAs: "HTML") + "<br><br>" + g.message(code:"registration.classSearch.field.courseNumberLevels.placeholder.tooltip", encodeAs: "HTML")}">

Removing encodeAs: "HTML" from the Input 2 causes it to display correctly.

<input title="${config.config.contains('keyword')? g.message(code:"registration.classSearch.field.keywordinputbox.placeholder.tooltip", encodeAs: "HTML"):g.message(code:"registration.classSearch.field.inputbox.placeholder.tooltip", encodeAs: "HTML") + "<br><br>" + g.message(code:"registration.classSearch.field.courseNumberLevels.placeholder.tooltip")}"

Removing the two <br><br> doesn't have any effect as expected. Changing the first g.message to a plain text message property has no effect as well.

The output for Input 1:

<input type="text" class="freeform search-input" title="<b>Undergraduate Level</b>:<br>0&amp;ndash;4999<br><br><b>Graduate Level</b>:</br>5000+">

The output for Input 2 with encodeAs:

<input title="These special characters are ignored: *^&amp;#39;!@$#&amp;amp;?[ ] ( ) |. The % is allowed.&amp;lt;b&amp;gt;Undergraduate Level&amp;lt;/b&amp;gt;:&amp;lt;br&amp;gt;0&amp;amp;ndash;4999&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;Graduate Level&amp;lt;/b&amp;gt;:&amp;lt;/br&amp;gt;5000+" type="text" class="freeform search-input">

The output for Input 2 without encodeAs:

<input title="These special characters are ignored: *^&amp;#39;!@$#&amp;amp;?[ ] ( ) |. The % is allowed.<b>Undergraduate Level</b>:<br>0&amp;ndash;4999<br><br><b>Graduate Level</b>:</br>5000+" type="text" class="freeform search-input">

I'd expect it to behave the same with and without concatenation, but it doesn't. Are we not supposed to concatenate this way?

UPDATE This SO thread about HTML tags in message.properties talks about HTML encoding to prevent XSS, which made me realize that encodeAs was doing what it's supposed to be doing - encoding the message as HTML. Removing the encodeAs allowed the HTML to render instead of being encoded as HTML entities.

But this still doesn't explain why Input 1's HTML is rendered while Input 2 has HTML entities.


Solution

  • This SO thread about HTML tags in message.properties talks about HTML encoding to prevent XSS, which made me realize that encodeAs was doing what it's supposed to be doing - encoding the message as HTML. Removing the encodeAs allowed the HTML to render instead of being encoded as HTML entities.

    So, there are two possible workarounds since I still don't know why encodeAs seems to be behaving differently:

    1. Leave the HTML in the message.properties and remove encodeAs: "HTML" from the g.message method
    2. Separate the original message into various parts and moving the HTML to the GSP