Ruby on Rails Helper Method - HTML is displayed as plain text - html

I have a helper method for my Rails app that returns a string with HTML code for a Google Groups subscription form. Unfortunately, it comes out on the page like plain text. How can I force it to render as HTML?
Thanks in advance.

The result of your helper needs to be marked as "html_safe" in Rails 3. Otherwise, the tags will be escaped.
def my_helper
data = "<p>Hello!</p>"
data.html_safe
end

I suppose it was a problem with Rails html sanitize.
from rails changelog
You no longer need to call h(string)
to escape HTML output, it is on by
default in all view templates. If you
want the unescaped string, call
raw(string).
try it

One thing to watch out for is when joining multiple strings like this
def custom_check_box(checked)
'<span class="my-custom-checkbox '+( checked ? 'checked' : '')+'"></span>'.html_safe
end
In this case, only the last part is marked as html safe. Make sure you get the whole thing.
def custom_check_box(checked)
('<span class="my-custom-checkbox '+( checked ? 'checked' : '')+'"></span>').html_safe
end

Related

node.js: is there no way to put HTML into i18n-node JSON translation files?

The question says it all. If I put HTML directly into the (JSON-formatted) translation file, like this:
"test_html" : "click <a href='http://stackoverflow.com/'>here</a>",
I get this in my HTML:
click <a href='http://stackoverflow.com/'>here</a>
I also tried combining this in my translation file:
"test_html_placeholder" : "click %shere%s",
With this in my HTML:
<%= __('test_html_placeholder', '', '') %>
But got similar results.
The only thing I can get to work is this clumsiness:
"test_html_pre" : "click ",
"test_html_link" : "here",
"test_html_post" : ".",
with this:
<%= __('test_html_pre') %><%= __('test_html_link') %><%= __('test_html_post') %>
But it's so cumbersome as to be almost not worth doing, and moreover the word order in some languages would force me to put some empty strings in my translation files, which i18n-node doesn't seem to like as it spits out the key (attribute) name when it
encounters an empty string.
I also tried using "\" as an escape character in front of the symbols, but I got an invalid JSON error when I lifted sails (restarted the server).
Any ideas, workarounds? I'm using sails.js, it wasn't my decision but I'm stuck with it and it comes with i18n-node. It's kind of late in the day on this project to consider using another library, but not completely out of the question.
beside of any upcoming discussion whether to include (html-)code in language files or not:
try to use
<%- __('click') %>
instead of
<%= __('click') %>
in ejs (the sails default template engine) a '<%=' will escape any html tags while '<%-' puts output as is without touching it. I am pretty sure you'll find unescaped html in your .json files. i18n doesn't do any transformation other than JSON.stringify() but almost all template engines do escape strings by default to prevent xssi.
For those using pug/jade, you can use
!{ __('key_for_your_text') }
Another option for pug is using
p!= __('key_for_your_text')

Using ruby variables as html code

I would expect that the following:
<div style="padding-top:90px;"><%= u.one_line %></div>
simply pulls whatever is in u.one_line (which in my case is text from database), and puts it in the html file. The problem I'm having is that sometimes, u.one_line has text with formatted html in it (just line breaks). For example sometimes:
u.one_line is "This is < / b r > awesome"
and I would like the page to process the fact that there's a line break in there... I had to put it with spaces up ^^^ here because the browser would not display it otherwise on stackoverflow. But on my server it's typed correctly, unfortunately instead of the browser processing the line break, it prints out the "< / b r>" part...
I hope you guys understand what I mean :(?
always remember to use raw or html_safe for html output in rails because rails by default auto-escapes html content for protecting against XSS attacks.
for more see
When to use raw() and when to use .html_safe

Why SafeHtml only shows plain text & does not show formmatted text (GWT)?

HTML myHtml=new HTML(SafeHtmlUtils.fromString("<i>Test</i>"));
HTML myHtml2=new HTML("<i>Test2</i>");
testHTMLPanel.add(myHtml);
testHTMLPanel.add(myHtml2);
OUTPUT:
<i>Test</i>
Test2
The right output should be the formmatted text like the second one. Other Gwt html widget also have the similar problem.
I am using Eclipse Juno.
SafeHtmlUtils.fromString(String s)
HTML-escapes its argument and returns the result wrapped as a SafeHtml.
That means that you get somthing like &#6.0;i&#.62;Test&#.60;&#.47;i&.#62;
Check
https://developers.google.com/web-toolkit/doc/latest/DevGuideSecuritySafeHtml
It's a security thing:
The reason why you have SafeHtmlUtils.fromString(userString) is that you can take a dynamic string, for example from a user input, and create a html text from it. It's more safe than just use Html.setText(userString) because with setText(userString) it would be feasible to inject vulnerable code.
more about input validation: http://www.testingsecurity.com/input-validation

Stop HTML Entites

Is there a way to stop a HTML entity from being rendered?
By that I mean that I'd like to have 2 lines. First is where the entity is rendered (e.g. &), and on the second line, I'd like to have the entity itself but not rendered (e.g. & - amp;).
I don't know if it helps, but I'm using WordPress to add both these lines.
Escape the ampersand. For instance, instead of render the ampersand as an entity: &nbsp;.
As per your example, use &amp;.
Simply use htmlentities() in php or htmlspecialchars()
wordpress is in php.so you can use those functions like this :
htmlspecialchars('your tags');

Conditional HTML Attributes using Razor

The variable strCSSClass often has a value but sometimes is empty.
I do not want to include an empty class="" in this input element's HTML, which means if strCSSClass is empty, I don't want the class= attribute at all.
The following is one way to do a conditional HTML attribute:
<input type="text" id="#strElementID" #(CSSClass.IsEmpty() ? "" : "class=" + strCSSClass) />
Is there a more elegant way of doing this? Specifically one where I could follow the same syntax as is used in the other parts of the element: class="#strCSSClass" ?
You didn't hear it from me, the PM for Razor, but in Razor 2 (Web Pages 2 and MVC 4) we'll have conditional attributes built into Razor (as of MVC 4 RC tested successfully), so you can write things like this:
<input type="text" id="#strElementID" class="#strCSSClass" />
If strCSSClass is null then the class attribute won't render at all.
Further Reading
Jon Galloway - ASP.NET MVC 4 Beta Released!
Conditional Attributes in Razor View Engine and ASP.NET MVC 4
Note you can do something like this(at least in MVC3):
<td align="left" #(isOddRow ? "class=TopBorder" : "style=border:0px") >
What I believed was razor adding quotes was actually the browser. As Rism pointed out when testing with MVC 4(I haven't tested with MVC 3 but I assume behavior hasn't changed), this actually produces class=TopBorder but browsers are able to parse this fine. The HTML parsers are somewhat forgiving on missing attribute quotes, but this can break if you have spaces or certain characters.
<td align="left" class="TopBorder" >
OR
<td align="left" style="border:0px" >
What goes wrong with providing your own quotes
If you try to use some of the usual C# conventions for nested quotes, you'll end up with more quotes than you bargained for because Razor is trying to safely escape them. For example:
<button type="button" #(true ? "style=\"border:0px\"" : string.Empty)>
This should evaluate to <button type="button" style="border:0px"> but Razor escapes all output from C# and thus produces:
style="border:0px"
You will only see this if you view the response over the network. If you use an HTML inspector, often you are actually seeing the DOM, not the raw HTML. Browsers parse HTML into the DOM, and the after-parsing DOM representation already has some niceties applied. In this case the Browser sees there aren't quotes around the attribute value, adds them:
style=""border:0px""
But in the DOM inspector HTML character codes display properly so you actually see:
style=""border:0px""
In Chrome, if you right-click and select Edit HTML, it switch back so you can see those nasty HTML character codes, making it clear you have real outer quotes, and HTML encoded inner quotes.
So the problem with trying to do the quoting yourself is Razor escapes these.
If you want complete control of quotes
Use Html.Raw to prevent quote escaping:
<td #Html.Raw( someBoolean ? "rel='tooltip' data-container='.drillDown a'" : "" )>
Renders as:
<td rel='tooltip' title='Drilldown' data-container='.drillDown a'>
The above is perfectly safe because I'm not outputting any HTML from a variable. The only variable involved is the ternary condition. However, beware that this last technique might expose you to certain security problems if building strings from user supplied data. E.g. if you built an attribute from data fields that originated from user supplied data, use of Html.Raw means that string could contain a premature ending of the attribute and tag, then begin a script tag that does something on behalf of the currently logged in user(possibly different than the logged in user). Maybe you have a page with a list of all users pictures and you are setting a tooltip to be the username of each person, and one users named himself '/><script>$.post('changepassword.php?password=123')</script> and now any other user who views this page has their password instantly changed to a password that the malicious user knows.
I guess a little more convenient and structured way is to use Html helper. In your view it can be look like:
#{
var htmlAttr = new Dictionary<string, object>();
htmlAttr.Add("id", strElementId);
if (!CSSClass.IsEmpty())
{
htmlAttr.Add("class", strCSSClass);
}
}
#* ... *#
#Html.TextBox("somename", "", htmlAttr)
If this way will be useful for you i recommend to define dictionary htmlAttr in your model so your view doesn't need any #{ } logic blocks (be more clear).