converting plain text to html - ruby-on-rails

My rails 3 app receives emails. Some of them are plain text. When the app displays them to the user I want them to be properly formatted. In other word I want to encode plain text into html. For example: "Hello\n\nHello" => HelloHello (or something like it).
Of course I can write my own 4 lines of code but I am sure those 4 lines have already be written, tested and wrapped in some nice method call.

I know I'm a little late, but I actually think the proper solution to this, at least within Rails, is to leverage the simple_format helper method provided from ActionView::Helpers::TextHelper.

Wrap your text in a Pre tag:
<%= content_tag('pre', "Hello\n\nHello") %>

Using #html_safe, let me explain with an example:
If in your controller the variable is:
#str = "<h1>Hi</h1>"
Then in the view:
<%= #str.html_safe %>

#Batkins has the right answer, which should be accepted.
if someone who is still looking,
Converting plain text to HTML
<%= simple_format("plain text") %>
Converting HTML to proper plain text
text.html_safe
The simple_format is TextHelper module so you if you want to use simple_format method in controller
include ActionView::Helpers::TextHelper

in your controller
render :text => "bla bla bla"
it be useful
http://apidock.com/rails/ActionView/Rendering/render

Related

Apply a class inside paragraph with HAML

I have got a problem with Ruby on Rails template using HAML.
I have no idea how to apply a specific class inside a tag, for example in:
%p My name is John Doe
I want to add a .highlight class to "name" word. How to do this? I only know this way:
%p
%span My
%span.highlight name
%span is John Doe
but of course it is not the best way to do this, I hope so. Any ideas?
No matter what, you have to put the highlighted text in its own element, so your code is pretty close. You don't need to wrap the rest of the text in elements, though:
%p
My
%span.highlight name
is John Doe
This will produce:
<p>
My
<span class="highlight">name</span>
is John Doe
</p>
Edit:
In the case of question marks, you can use Haml's succeed helper method:
%p
= succeed "?" do
What's your
%span.highlight name
This will render:
<p>
What's your
<span class='highlight'>name</span>?
</p>
There are also precede and surround methods, which you can read about here: http://haml.info/docs/yardoc/file.REFERENCE.html#helper-methods
If you'd rather use string interpolation, it's probably be easiest to define your own helper method.
def hl(str)
capture_haml {
haml_tag 'span.highlight', escape_once(str)
}.strip!.html_safe
end
Since this is kind of elaborate, let me break it down from the inside out. First, we need to escape the string with escape_once. This is only necessary if str comes from user input (and so could lead to an XSS attack), but it's good to have in any event. Then we use haml_tag to render the string inside a span.highlight. Then we have to capture this output as a string with capture_haml, since we're using it in interpolation (ordinarily haml_tag writes to the Haml buffer instead of returning a string). Then we use strip! because Haml will render a newline after this, and you said you don't want that. Finally, we use html_safe to tell Rails not to escape the output, since it would break our <span> and we already escaped the input so we know it's safe.
Now you can use the hl method in your interpolated Ruby:
%p
What's your #{hl "name"}?
This will render:
<p>
What's your <span class='highlight'>name</span>?
</p>

Rails escapes string inside label tag

I have a label tag, whose content is loaded from a en.yml file.
html.erb
<%=label_tag(:name, t(:name, scope:[:helpers, :form], name: person_name(person))).html_safe%>
person_name is a helper and outputs a string
persons_helper.rb
def person_name(person)
content_tag(:span,
formatted_name(person.name) || t("helpers.persons.default_name"),
class: 'name').html_safe
end
output string from the helper is passed on t method and concatenated as following
en.yml
name: "Person Name: (%{name})"
I want the output to be like
<label for="person">
Person Name:
<span class='name> John Doe </span>
</label>
but Instead I get
<label for="person">
Person Name:(<span class="name">John Doe</span>)
</label>
I understand that it got to do with html_safe, raw and escaping strings but I just could not get it to work!
Thanks!
Call .html_safe on the method call inside the label_tag. E.g:
<%=label_tag(:name, t(:name, scope:[:helpers, :form], name: person_name(person).html_safe))%>
It appears that the I18n.t method does not return a SafeBuffer (i.e. an html_safe string). So you should call .html_safe on the output from this method.
<%= label_tag(:name, t(:name, scope:[:helpers, :form], name: person_name(person)).html_safe) %>
Note the .html_safe call has been moved in one parenthesis from where you had it. This can also be made marginally easier to see by using the block form of the label_tag helper.
<%= label_tag(:name) { t("helpers.form.name", name: person_name(person)).html_safe } %>
Note: I also switched to the "helpers.form.name" method of selecting the I18n translation in this example to further increase readability (but this may be just a personal preference -- so use your original style if you prefer!).
Finally, for security purposes -- so that a user's name doesn't come through unescaped -- you should remove the .html_safe from your person_name helper and add a strict html_escape (or sanitize) so that it looks like this:
def person_name(person)
content_tag(:span,
h(formatted_name(person.name)) || t("helpers.persons.default_name"),
class: 'name')
end
In this form, the content_tag will make sure everything is html_safe except for the content. Meaning that the person.name will come through as is and be escaped as needed. However, this is not needed if the formatted_name method returns an already escaped or html_safe name. Basically the point is that you don't want to blindly mark strings as html_safe when they come from user inputted values because you don't know if they contain script tags or what. Hopefully this didn't confuse. :) In general, only mark strings as html_safe when you are 100% sure that they are actually always going to be safe (i.e. they come from within your system and not from user input of any sort).
Rails translations can be automatically marked as html_safe but using a naming convention. If a translation is suffixed with _html then the string is marked as html_safe, likewise keys named html are also marked as html_safe.
# config/locales/en.yml
en:
welcome: <b>welcome!</b>
hello_html: <b>hello!</b>
title:
html: <b>title!</b>
In the above t('hello_html') and t('title.html') will be html_safe strings and will not require a call to raw or .html_safe where as t('welcome') will not be html_safe and will require calling raw or .html_safe to avoid the html in the string being escaped.
See http://guides.rubyonrails.org/i18n.html#using-safe-html-translations

Line breaks not displaying in view

I have Person.description with the following stored in the database:
jnkl
fdsfdsf
fdsf
fsdfdsfs fds fd sf sdf ds
How do I display this with the line-breaks in the view? It is currently displaying all on one line and I don't understand why.
you should use the simple_format helper:
<%= simple_format #person.description %>
http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-simple_format
Source
# File actionview/lib/action_view/helpers/text_helper.rb, line 301
def simple_format(text, html_options = {}, options = {})
wrapper_tag = options.fetch(:wrapper_tag, :p)
text = sanitize(text) if options.fetch(:sanitize, true)
paragraphs = split_paragraphs(text)
if paragraphs.empty?
content_tag(wrapper_tag, nil, html_options)
else
paragraphs.map! { |paragraph|
content_tag(wrapper_tag, raw(paragraph), html_options)
}.join("\n\n").html_safe
end
end
The reason why, is that in plain HTML, outside of containing tags such as 'xmp', line breaks aren't rendered as linebreaks, for the most part they are ignored. For them to show up, you need to replace them with 'br' tags, or something else that has a style or structure associated with it, like p tags, or even divs, depending on the content is.
This should do what you ask:
#person.description.gsub(/\n/, '<br />')
The built in Rails helper simple_format will also work, using p tags
http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-simple_format
I also use
#person.description.gsub(/\n/, '<br/>').html_safe
to display them in the view
Instead of replacing \n to <br> tags, which would consume a lot of processing if its a huge text, use css white-space: pre to break lines on \n.
Source: An html tag other than a textarea where \n is correctly interpreted
simple_format did not suit my needs as I want to be able to show multiple line breaks. simple_format makes 2 or more line breaks a paragraph.
So, I used css white-space: break-spaces; instead. The only current drawback is the browser support is 89.5% now.

Showing linebreaks in Rails3

I store the linebreaks as "line\n\nline" in the database.
When i am displaying it, I convert it using this method:
def showLineBreaks(from_textarea)
from_textarea.gsub(/\n/,"<br/>")
end
But these renders the text as
line<br><br>line
instead of showing the linebreaks.
What is the right way to do this?
You probably need to flag your content as html_safe for it to display properly, otherwise the view will render it as the string should be displayed.
<%= showLineBreaks.html_safe %>
If you're trying to display newlines saved from text areas, you could do the following in your view:
<%= simple_format from_textarea %>
No need to do manual substitution in this case.

rails3 + liquid parse question

I have a question in using luquid. My question is like this,
I have a model called 'Page' (with is an ActiveRecord::Base
inherited) , and it has a column called 'content' which will store
the html page content.
I have a code to display it as follows
<%#template = Liquid::Template.parse(page_content) %>
<%= #template.render('page_content' => yield) %>
where 'page_content' has implemented in application helper as follows
def current_site_layout
Page.find(1). content
end
but my problem is if I have content as follows
<h1>This is a test</h1>
It will display in the page as
<h1>This is a test</h1> (with <h1></ h1> tags)
where as I want it to print like This is a test (formatting
applied as h1)
what am I missing here , and I think I will have to use liquid_methods
or something like that. But since I'm new to liquid I'm not sure which
method to use.. can someone help me
I'm on rails3 and using gem 'liquid 2.2.2', from 'github.com/GnomesLab/
liquid.git'
thanks in advance
cheers
sameera
In rails 3, strings are escaped by default. To display unescaped strings, you need to call raw method explicitly.
<%#template = Liquid::Template.parse(page_content) %>
<%= raw #template.render('page_content' => yield) %>

Resources