Reputation: 22519
I have something like this:
<p>
<b>Tags:</b>
<%if @post.tags.count > 0%>
<%= @post.tags.collect {|c| (link_to c.name, c)}.join(", ")%>
<%else%>
Does not have any tags.
<%end%>
</p>
Which gives me
Tags: <a href="/tags/1">Java</a>, <a href="/tags/2">CSS</a>
Instead of Java and CSS links. What am I missing?
Upvotes: 1
Views: 3305
Reputation: 16011
I think your tag names should be input by the user, right?
In this case, html_safe
is not your first choice, as it gave full trust to the user. And your site would encounter XSS attacks.
The better choice should be sanitize
. See the reference here: http://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html
As you only want to have links, the following line do what you want:
<%= sanitize @post.tags.collect {|c| (link_to strip_links(c.name), c)}.join(", "), :tags => %w(a) %>
Note the use of strip_links(c.name)
, this removes all the links that input by the user.
Let's assume the tag names are: ["Product", "hi", "bye"]
By just using .html_safe
, the following would be shown:
<a href="/tags/1">Product</a>, <a href="/tags/2"><strong>hi</strong></a>, <a href="/tags/3"><a href='bad_site.com'>bye</a></a>
But using the mix of sanitize with strip_links, the following is the result:
<a href="/tags/1">Product</a>, <a href="/tags/2"><strong>hi</strong></a>, <a href="/tags/3">bye</a>
Or you could mix the use of strip_tags
with .html_safe
:
<%= @post.tags.collect {|c| (link_to strip_tags(c.name), c)}.join(", ").html_safe %>
This simply removes all tags in c.name
before you call the html_safe.
I would suggest (and you probably are doing already :D) removing all unwanted tags before storing into the database.
Upvotes: 1
Reputation: 8400
It's because strings in Rails 3 are, by default, not considered HTML-safe. See this blog post about it.
You can manually mark something as safe by calling .html_safe
on it, which would make your code like so:
<p>
<b>Tags:</b>
<%if @post.tags.count > 0%>
<%= @post.tags.collect {|c| (link_to c.name, c)}.join(", ").html_safe %>
<%else%>
Does not have any tags.
<%end%>
</p>
But I'd recommend doing this instead:
<p>
<b>Tags:</b>
<% if @post.tags.count > 0%>
<% @post.tags.each_with_index do |tag, i| %>
<%= link_to h(tag.name), tag %><%= ', ' if i < @post.tags.size - 1 %>
<% end %>
<% else %>
Does not have any tags.
<%end%>
</p>
Upvotes: 6
Reputation: 7809
I think html_safe is what you are looking for! So this would solve the problem (@post.tags.collect {|c| (link_to c.name, c)}.join(", ")).html_safe
Upvotes: 3