What techniques/methods are there for dealing with emphasized or stylized text in localized strings?
For example, how might a brief title such as the one below (4–8 words) be italicized?
Welcome to the Machine, John.
Is there a more efficient way than 3 lookups, plus a variable to define the structure?
Check out documentation it says:
Third, it'll mark the translation as safe HTML if the key has the suffix “_html” or the last element of the key is the word “html”. For example, calling translate(“footer_html”) or translate(“footer.html”) will return a safe HTML string that won't be escaped by other HTML helper methods. This naming convention helps to identify translations that include HTML tags so that you know what kind of output to expect when you call translate in a template.
So you need to append suffix _html to your key and now you can use html in your locales.
For example this is your locale file:
en:
welcome:
html: '<b>Hello!</b> This is first way to style your locales!'
welcome_html: '<b>Hi again!</b> This is second way to style your locales!'
Now just set I18n.t 'en.welcome.html' or I18n.t 'en.welcome_html' in your views. That's all! :)
Related
I have a following translation:
welcome: Hello there, %{general_kenobi}
Now I know, that I can put HTML tags in the translation, like <em> or so. But what if I want this general_kenobi to have my custom style? How do I implement it? I've tried to google it, but didn't find anythin useful (or maybe I'm just bad at googling). Thank in advance!
If you want to add something fancy like this to your locale you must add the _html extension to the key.
From the docs
Keys with a '_html' suffix and keys named 'html' are marked as HTML
safe. When you use them in views the HTML will not be escaped.
en:
welcome_html: "<b>Bolded text</b>"
then just the regular stuff in your views
<%= t('welcome_html')
I've read in multiple places that as of Rails 3 you no longer have to use html_escape "some string" to actually escape a string in a view and that simply writing <%= "some string" %> would escape the string by default. However, I cannot find this information in the docs. I read through the XSS in the Rails guides section that stated this:
https://guides.rubyonrails.org/security.html#cross-site-scripting-xss
As a second step, it is good practice to escape all output of the application, especially when re-displaying user input, which hasn't been input-filtered (as in the search form example earlier on). Use escapeHTML() (or its alias h()) method to replace the HTML input characters &, ", <, and > by their uninterpreted representations in HTML (&, ", <, and >).
Then I see several blogs that state that it is escaped by default. For example: https://www.netsparker.com/blog/web-security/preventing-xss-ruby-on-rails-web-applications/
https://dzone.com/articles/preventing-cross-site-scripting-vulnerabilities-wh
Found it:
https://guides.rubyonrails.org/3_0_release_notes.html
"7.4.3 Other Changes
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)."
escapeHTML() (or its alias h()) are from CGI::escapeHTML, which is a Ruby API implementation. If you aren't using Rails you still have a way to escape HTML. Rails may do some automagical handling of HTML in ERB files for display, and that is what you are probably referring to with html_escape "some string" and <%= "some string" %>. I think you are possibly confusing html_escape which you might need when displaying urls and such that are stored in the DB and you want the ERB processor to not mess it up? I know sometimes, particularly in .js.erb files I need to escape some things to get the result I was expecting. This is different than sanitizing. It seems in your example they are referring to something that you might accept and then redisplay, like a search string. If you put <i>hello</i> into a search box you would want to sanitize the input before passing it to the back end, or if you are using some javascript to filter you might want to escape it both for security reasons and to let it re-display correctly in the search box after you've filtered.
Edit: I was not able to find the answer to your comment in the ri doc either. But I tried:
<%= "<b>hello</b>" %>
<%= h("<b>hello</b>") %>
And got the same result in the browser:
<b>hello</b>
<b>hello</b>
So if you are asking if it is true, then I would say yes.
Assuming no tags are allowed in the user input and we want to sanitize user input before storing it in the database, in Rails, we have the options of using sanitize (whitelist an empty set of tags) and strip_tags.
Which is better against XSS attacks? If something else is even better, what is that? And why is it better?
As of Rails 3 and the fatty beatdown the Rails core dev team took when they made Rails unsafe by default, all strings are now tagged as either safe or unsafe with "unsafe" strings being the default. You only need to think about explicitly managing the "safeness" of strings in Rails when you're writing helpers that output HTML into your template.
Escaping vs Sanitizing:
In this context, escaping means replacing some of the string characters with an HTML escape sequence that will remove the special meaning from the text and cause it render as regular text. Sanitizing on the other hand, means validating the HTML content to ensure only good HTML tags and attributes are used. Note that sanitizing is inherently less secure than escaping because of this and should only be used where rendered content must contain HTML markup. An example would be a WYSIWYG HTML editor on a textarea that manages code that is later rendered on a page.
Sanitize encodes all tags and strips all attributes (not specifically allowed which is all in your case) from the html string passed to it. It also strips href and src tags with invalid protocols to prevent any abuse of js attributes. Strip_tags on the other hand will strip all supplied tags including comments which sounds like exactly what you want. As long as you're whitelisting params and adding them to your DB properly escaped such as:
Title.where(author = ?, author_id)
and not blindly inserting user input into your db I would be comfortable with how you're setup.
In my rails application, people are supposed to submit "posts." However, in the default scaffolding, there are some problems in the text input: not allowed HTML code, changing the line doesn't work, etc. From what I've learned, I need to use a markdown-markup language to solve this issue. Is there a guide for me to follow to apply such language to solve my problem?
UPDATE: Here are my problems.
1) Every sentence is combined into one line even if I put a line space.
first line
second line
becomes
first line second line
2) I can't make text bold, italicized, or hyperlink. Like in stackoverflow, user should easily put <b> and make bold text, ** to make italicized, etc. And URL address should automatically be translated to href link.
To do these, I thought I had to use markdown library. I could be mistaken, so I needed someone to guide me through. Railscasts on Markdown
Well, yes, new lines in HTML have no meaning. You need to replace line breaks with <br> to preserve them in HTML. To automatically highlight links, you need to look for links in the text and wrap them in appropriate <a> tags. Finally, if you're not filtering HTML tags, they should still be in there. It all depends on what you're doing. Markdown is something entirely different, a special markup language that enables you to do the above while being easier to write than HTML. It depends on what you want to use.
Whenever I use Html.ActionLink it always Html encodes my display string. For instance I want my link to look like this:
More…
it outputs like this: More…
&hellip is "..." incase you were wondering.
However the actionlink outputs the actual text "…" as the link text. I have the same problem with if I want to output this:
<em>My-Post-Title-Here</em>
I wind up with:
<em>My-Post-Title-Here</em>
Any idea how to do this?
It looks like ActionLink always uses calls HttpUtility.Encode on the link text. You could use UrlHelper to generate the href and build the anchor tag yourself.
<a href='#Url.Action("Posts", ...)'>More…</a>
Alternatively you can "decode" the string you pass to ActionLink. Constructing the link in HTML seems to be slightly more readable (to me) - especially in Razor. Below is the equivalent for comparison.
#Html.ActionLink(HttpUtility.HtmlDecode("More…"), "Posts", ...)
The answer given by Sam is actually correct and I used it in my solution so I have therefore tried it myself.
You may want to remove the extra parenthesis so it becomes something like this:
#Html.ActionLink(HttpUtility.HtmlDecode("&"), "Index", "Home")
Alternatively, just use a plain Unicode ellipsis character \u2026 and let MVC worry about how to encode it. Unless there's some particularly compelling reason you'd specifically need a hellip entity reference as opposed to a character reference or just including the character as simple UTF-8 bytes.
Alternative alternatively: just use three periods. The ellipsis (U+2026) is a compatibility character, only included to round-trip to pre-Unicode encodings. It gets you very little compared to simple dots.
Check out this:
<p>Some text #(new HtmlString(stringToPaste)) </p>
Decode it before passing the value in. Just had this same issue (different characters) and it works fine:
Eg:
#Html.ActionLink(HttpUtility.HtmlDecode(_("&")), "Index", "Home")
Annoying though