Rails 3 added a security protection against Cross-site scripting per default. This is a good thing because it makes your web application safer, but it also can cause troubles when you are using html in your translations. What Rails does, is to distinguish between ‘html_safe’ and not ‘html_safe’ strings. When a string is not safe, it will be always escaped. Hence, your HTML tags are shown in the text and not used as actual HTML tags.
What does that mean in your code? Let’s digg in:
Let’s say we want a formatted text like this:
LingoHub (h2 tag)
can’t wait to see it (text enclosed in p tag)
Of course we use a resource file to store our text, so our application is ready to go global. And for demonstration purposes we put the HTML tags in the text (something I normally don’t recommend). Here is our resource file:
All these translation have the text from above and the key is named after the method we use to display them.
And here is the code with the results:
The first line translates the string and puts it right in the view. Since the string isn’t marked as html_safe, the tags are escaped using < and >.In doing so, Rails makes sure that when you display text from an untrusted source (e.g. user inputs), no harmful code can be embedded in your site. Line 2 uses the raw method to create a new string that is marked html_safe. Line 3 uses the html_safe method, which works like the raw method. Note, no raw! or html_safe! method exists to mark the existing string html_safe. There will be always a new string object created. Most interesting is Line 4 which shows a handy convention. When a translation title ends with “_html”, Rails assumes that the text contains HTML and you don’t want to escape it.
Like above mentioned, I am not a big fan of using HTML in your translation texts, but if you do, I would recommend to stick to the “_html” convention. It keeps the code cleaner and shows you right at the source if a translation text will be escaped or not.
Have fun translating!