ElonTheFreemason
ElonTheFreemason

Reputation: 107

HTML and Ruby on Rails - Display <br/> tags as line breaks, but other tags as strings

I'm working on my first Rails website, but I have a little problem: I want to display the <br/> tags as line breaks, but I also want to display the other tags as strings.

For example, the user input is:

<a href='#2'>Go to #2</a><br/><a href='#3'>Go to #3</a>

I want to display:

<a href='#2'>Go to #2</a>
<a href='#3'>Go to #3</a>

I know that I can display the <br/> tags as line breaks like this:

<%= simple_format @user_input %>

But the problem is that this command display:

Go to #2
Go to #3

And not:

<a href='#2'>Go to #2</a>
<a href='#3'>Go to #3</a>

Thank you in advance!

Upvotes: 3

Views: 2112

Answers (2)

Gerry
Gerry

Reputation: 10507

You could do something like this:

<% @user_input.split("<br/>").each do |line| %>
  <%= line %><br/>
<% end %>

Output:

<a href='#2'>Go to #2</a>
<a href='#3'>Go to #3</a>

Or even better, use a regexp so you can split either <br> or <br/>:

<% @user_input.split(/<br\/>|<br>/).each do |line| %>
  <%= line %><br/>
<% end %>

UPDATE

Some cases will fail with the above approach, for example:

<input type="text" value="<br/>">

To be able to handle those cases, you could use Nokogiri, already bundled with rails, but you'll need add a couple of additional steps in your code.

First, your controller:

def some_action
  input = "<a href='#2'>Go to #2</a><br/><a href='#3'>Go to #3</a><br><input type='text' value='<br/>'>"

  @user_input = Nokogiri::HTML.parse(input)
  @user_input.search('br').each { |br| br.replace("\n") }
end

Basically, you will create a Nokogiri HTML document and replace all br tags with "\n".

Second, create a css class to use those "\n" as break lines:

.new-lines {
  white-space: pre-line
}

Now you will simply add this to your view:

<div class="new-lines">
  <%= @user_input.css('body').children %>
<div>

Notice the use of class="new-lines", this is important to make each "\n" act as a <br>.

And the output:

<a href="#2">Go to #2</a>
<a href="#3">Go to #3</a>
<input type="text" value="&lt;br/&gt;">

Yes, there is a small caveat since the original value='<br>' turned into value="&lt;br/&gt;", but i hope that not to be a big issue; but if it is, then you could do something like this:

<%= @input.css('body').children.to_s.gsub("&lt;", "<").gsub("&gt;", ">") %>

And the output:

<a href="#2">Go to #2</a>
<a href="#3">Go to #3</a>
<input type="text" value="<br/>">

You may need to enhance this code further for more edge cases, but i think this example will do the trick.

Also consider using a helper instead of throwing all the code in your controller/view.

Upvotes: 1

Steve Carey
Steve Carey

Reputation: 3034

Use the Rails sanitize helper method and whitelist the tags you want to allow and leave those out that you don't. All those left out would be stripped and shown as text. So in your case it would be something like

<%= sanitize @user_input, tags: %w(br) %>

For the sanitize method api info see http://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html#method-i-sanitize.

Upvotes: 6

Related Questions