Ruby/Rails - Parsing and Displaying HTML from a Models Attribute - ruby-on-rails

I have a Rails Model called Events which has as field/attribute called :description.
I migrated it under the type t.text rather than t.string since I was going to be displaying a large amount of data.
So.... Now I'm at the point where I would like to display <%= #event.description %> in a neat way and would like to break up some of the sentences rather than one large block of information.
I was hoping I could insert <p> or other html codes to help with how the text is displayed.
The problem is inserting <p> into the field only prints <p> and the not desired action of the html command.
How can I add html styling to the text attribute?

You can use <%=raw #event.description %> to echo unescaped content. Be aware that this is a potential XSS security hole, if users can ever affect that content. I highly recommend using the sanitize helper to strip out any unwelcome markup before you write it out.

It strictly depends on how you print it. In particular, if you print with calling h function (<%= h my_text =>), output will be sanitized and html escaped.
It may also depend on your rails version: I've head in Rails 3 html is escaped by default, even if you don't use h.

Related

Safe Rails HTML translations

Following the rails guides as per the posting title, the YAML local files were set in a Rails 6.1.3 application as follows:
authorisation_request: Payment to be authorised; </br>Final <b>exact charge</b> </br>will reflect <b>delivered goods</b>.
authorisation_request_html: Payment to be authorised; </br>Final <b>exact charge</b> </br>will reflect <b>delivered goods</b>.
In the view, three experiments were conducted:
<i><%= t('cart.authorisation_request').capitalize %></i>
<i><%= raw t('cart.authorisation_request_html').capitalize %></i>
<i><%= t('cart.authorisation_request_html').capitalize %></i>
The first one rendered the tags as expected straight text, the middle one rendered as expected both the break and bold tags.
But the last one was rendered identical to the first. What am I missing?
When a translation key has the _html suffix, you can call it as if it did not, and it will automatically treat the key as HTML safe.
The way you are displaying the translation key is not as intended, instead of doing:
<%= t('cart.authorisation_request_html').capitalize %>
You should be doing:
<%= t('cart.authorisation_request').capitalize %>
Then the I18n system will see that there is an _html-suffixed variant, and mark that as HTML safe to display as-is. The way you are doing it now, the system would be looking for a key named authorization_request_html_html (double suffixed) and not find it.
More info on Safe HTML Translations: https://guides.rubyonrails.org/i18n.html#using-safe-html-translations
As a side-note, you should probably be capitalizing your source translated text, and not modifying it afterwards with the .capitalize helper. If that text were translated to another language, the capitalization could probably look pretty strange in some languages.

Rails 4: how to insert line breaks in text_area?

I have created a blog in rails. I'm a beginner and got quite far, but now I'm stuck with a seemingly minor detail: I can't seem to format the posts (articles).
Here's the relevant part of my show.html.erb:
<p>
<strong>Content:</strong>
<%= simple_format (#article.content) %>
</p>
When I write something and insert html-tags, they are not recognized as such. What am I doing wrong?
Rails will automatically remove html tags to prevent someone from injecting code into your webpage (e.g. malicious javascript)
If your users cannot enter data into #article.content and it's always safe then you can flag it as safe usng the html_safe method.
<%= (simple_format (#article.content)).html_safe %>
Can you post the article content for reference? If I had to guess, I'd imagine Rails is escaping the html tags and inserting them as plain text (so the output looks like: Article content !
Take a look at Rails' helper methods like content_tag (http://apidock.com/rails/ActionView/Helpers/TagHelper/content_tag) and concat (http://apidock.com/rails/ActionView/Helpers/TextHelper/concat) and consider using those to help with generating the appropriate html tags.
An issue to be concerned with is who's going to be supplying the content. For example, if you're writing an application that other people will use, you want to make sure any html give you is escaped to avoid XSS attacks. In that case, you'll want to spend some time reading about how to properly sanitize user input.
You can now specify the tag it gets wrapped in (defaults to p) like so:
<%= simple_format (#article.content, {}, wrapper_tag: "div") %>
or
add white-space: pre-line style.
It will display \r or \n (enter) in user input as a new line.
for more info:
http://apidock.com/rails/v4.0.2/ActionView/Helpers/TextHelper/simple_format

Rails translation performance impact <%= raw t( vs. <%= t(

I am building a multilingual application using rails-i18n Ruby on Rails.
Most of content (and DB entries) I have to translate is pure text, though part of it has some embedded html.
I was thinking of using <%= raw t('translation_key') %> instead of the straight <%= t('translation_key') %> to account for future changes that might include html.
If I adopt <%= raw t('translation_key') %> throughout the all website, am I going to get any (negative) impact when it comes to
website performance
website security
You just just append _html to your tag keys to handle HTML in translation tags:
en:
key_one: test text
key_one_html: <p>test text</p>
Then the standard code will work:
<%= t('key_one_html') %>
Performance aspect:
The performance impact should be negligible. Calling raw copies the parameter into a new string (an ActiveSupport::SafeBuffer to be precise) with its html_safe flag set to true. On the other hand there is no longer HTML escaping performed on that string.
Security aspect:
There are more substantial drawbacks to using raw everywhere.
You say your translations are read from the database. Can the user edit these translations? If so...
You risk HTML injections: A malicious user could just enter a <script> tag.
All your translations must to be HTML safe from now on. That means you have to manually escape all your translations, i.e. you have to replace <,>, and &.
Alternatives:
There are other options if you need to incorporate HTML into your translations:
Use the _html suffix judiciously to prevent automatic escaping
Use localized views and partials, i.e. index.en.html, _footer.de-DE.html to translate larger parts of your views.
To streamline translation of database entries, you try
Globalize
hstore_translate (PostgreSQL only)
Conclusion:
Using raw everywhere will lead to a lot of problems along the road. Save yourself a lot of trouble and just use it "as needed".
You could also use the globalize gem for bigger text / html sections of content.
https://github.com/globalize/globalize/blob/master/README.md
It also supports eager loading if you're worried about performance.

Rails - Outputting content, sanitize or <%=h?

I recently made a small rails3 app to convert an old cms written in another language. After migrating the content I am having problems outputting content from the database.
The #content.desc field sometimes has html. Currently the only way I could get it to work was:
<%= sanitize content.desc %>
But is this the best way? When I use <%=h #content.desc %> I can see the html tags still. When I use <%= simple_format #content.desc %> I get wicked spacing.
Is there a definitive guide somewhere where I can see all of the options while outputting content? I've tried to search but can't turn anything up (rails newb, i know).
Any string not marked as "safe" will be HTML-escaped by default in Rails 3. Some methods, such as sanitize, h, link_to and many other helpers return safe strings, thus allowing them to be written literally. See this blog post for more info.
If you know for sure that the HTML contained in #content.desc is safe, you can mark it as such yourself like so: <%= #content.desc.html_safe %>.
Rails 3 has changed HTML sanitisation to be enabled by default. If you're sure that the string you're rendering is safe, you can use
<%= #content.desc.html_safe! %>
Unless I'm mistaken, you shouldn't have to sanitize the content before displaying it, as Rails 3 does that by default. More info here: http://yehudakatz.com/2010/02/01/safebuffers-and-rails-3-0/

Correct coding convention for embedded code on web page templates

I had come experience with PHP a time ago and now I'm learning to use Ruby on Rails. But one simple question bothered me in both these languages, so I think I can cross-post it to both tags.
As you know, one of the concepts there is that one can embed PHP or Ruby code into web page template. Then these statements are executed and result of its execution is inserted in certain places of the page, marked with "brackets" <%= ... %>.
Or... wait. We program Ruby/PHP, but not HTML. Maybe we should treat template as Ruby/PHP code, into which sometimes HTML markup is inserted? So the process is treated like that HTML are inserted into ruby code into the "brackets" %> ... <%.
These are two different approaches:
HTML page is the primary entity, and it is affected by code execution; or
code is the primary entity, and it is executed, while HTML snippets are inserted in certain places.
This philosophy leads to different possibilities in coding conventions: result of code execution influences the page If we adhere the first insight, then the code would look like this:
<p>
<% (1..10).foreach do |i| %>
Iteration number <strong><%= i %></strong>. <br/>
<% end %>
</p>
But if we stick to the second alternative, the code would be formatted like this:
<%
%><p><%
(1..10).foreach do |i|
%>Iteration number <strong><%
%><%= i %><%
%></strong>. <br/><%
end
%>
How should the concept of templates be construed? What concepts do you, way more experienced Web developers, account for the coding convention?
If this is in your View layer (and it should be), then the HTML is the primary entity. It's the most pertinent part of that layer -- marking up your data to display in meaningful ways to the user.
Even aside from that, your second example is nearly unreadable. I see what you're doing, but it took me a minute to wrap my brain around it. I've also never, ever seen View-layer code like your second example (and I would make it one of my priorities to change it wherever I saw it if it was in a project I was working on).
To be more concise: you're putting the emphasis on the wrong thing. In my opinion, readability trumps just about everything else. The coding style that produces the most readable code is therefore the most superior (ceteris paribus and YMMV, of course).
Maybe you should look into Haml? I don't know if there's a php equivalent, but as far as Rails goes, it's somewhere in between the two schemes. It's not quite code centric. But when used right, all the raw html is prepared programatically.
In short everything is considered text to be directly outputted, unless prefixed with either a %, - or =. Which translate to html-tag, ruby code that doesn't output. Ruby code that does output. Haml then uses whitespacing to nest things properly, much like python does. Raw html outputs untouched but using % to specify a tag handles closing tags.
Sample:
#outer-div
- #items.each do |i|
%span.item
= i
%br
Outputs
<div id="outer-div">
<span class="item">
item
</span>
<br>
</div>
See the haml tutorial for more information.
To answer the central question. The bulk of any page is going to be HTML or raw text. We reduce the bulk of that text with includes and helpers, but it's still there. If there were a truly code centered approach my use of it would depend on the ratio of program logic to html. Personally I'd rather go with the html centered approach.
If you are interested in a code-oriented view, this is something you might try implementing as a pure Ruby DSL:
tag :p, :class => 'iterations-container' do
(1..10).each do |i|
text "Iteration number "
tag :strong { text i }
text "."
tag :br
end
end
Or perhaps instead of tag :p do ... end, you may favor tag.p do ... end.
I recommend doing only very simple logic in your template files. That way designers who can edit HTML can easily edit even those files to alter the layout if need be.

Resources