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: Java, CSS
Instead of Java and CSS links. What am I missing?
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>
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
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:
Product, <strong>hi</strong>, <a href='bad_site.com'>bye</a>
But using the mix of sanitize with strip_links, the following is the result:
Product, <strong>hi</strong>, bye
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.
Related
I am using the ternary operator for single-line conditions, with erb printing tag <%= %>
<p>Status:
<%= notification.read? ? "Read" : link_to "Mark as Read", "/" %>
</p>
I need to give a mark as read link in false condition, in the above scenario getting the syntax template error, here notification is an object of the Notification model.
I want output as-
mark as read
mark as read would be link.
thanks!
Don't use a ternary:
<% if notification.read? %>
Read
<% else %>
<%= link_to 'Mark as Read', '/' %>
<% end %>
Or use parentheses in the link_to method call:
<%= notification.read? ? 'Read' : link_to('Mark as Read', '/') %>
Remember that anything inside <%= ... %> is just Ruby and that link_to is just a Ruby method like any other.
I'm totally stuck on looping through a form.select in Rails (using Elastic Search/Searchkick aggs).
I can access the 'bucket' array (and thus "key" and "doc_count") when I don't pre-pend the form.select helper, but it just doesn't loop through when it's there. Not sure how I would get the options dynamically otherwise!
Does anyone know what might be going wrong (ignore the link_to stuff, I'll be changing that once I can get the actual "key")? Perhaps I'm using the form.select helper incorrectly? Thanks!
<% form.select #jobs.aggs["location"]["buckets"].each do |bucket| %>
<% if params[:location] == bucket["key"].to_s %>
<strong><%= link_to bucket["key"], request.params.except(:location)%></strong>
<% else %>
<%= link_to bucket["key"], request.params.merge(location: bucket["key"])%>
<% end %>
<% end %>
I figured it out! It was a syntax error on my part, as I forgot to use :location in the first part of the form.select, and additionally didn't wrap the block after this in [] brackets (presumably the options have to be in an array or hash with this helper).
Here is the code (simplified) which solved this for me:
<% form.select :location, [#jobs.aggs["location"]["buckets"].each do |bucket| %>
<%= bucket["key"] %>
<% end ] %>
This is so simple but it's been ages since I needed this.
I have the following code
<% #miniature.minisets.each do |miniset| %>
<%= link_to miniset.name, miniset %>
<% end %>
It outputs Minisetname Minisetname Minisetname etc
I want it to output Minisetname, Minisetname, Minisetname with commas.
I've tried to include .join(", ") but can't find the right place to put it. Do I also need to use .map instead of .each?
Ignominy.
Here's one way that ought to work:
<%= #miniature.minisets.map { |miniset| link_to miniset.name, miniset }.join(", ").html_safe %>
Using Rails 3. This is a front-end design question.
Goal:
Contact | Email | URL
show.html.erb:
<% if !#shop.contact.blank? %>
<%= #shop.contact %>
<% end %>
<% if !#shop.email.blank? %>
<%= #shop.email %>
<% end %>
<% if !#shop.url.blank? %>
<%= link_to #shop.url, #shop.url, :target => "_blank" %>
<% end %>
How do I put in | only when the previous and after element has values? At current stage, if there is no value, nothing is output.
Many thanks.
<% url = link_to(#shop.url, #shop.url, :target => "_blank") if #shop.url.present? %>
<%= [#shop.contact, #shop.email, url].select(&:present?).join(" | ") %>
This creates an array of all your elements, selects those which have a value (as present? is the opposite of blank?) and then joins each element of the remaining array by putting a pipe between them.
That said, if you have more complex logic, you should probably create a helper method. The ERB templates are not a good place for complex logic. This above is bordering acceptable.
I'm undoubtedly missing something obvious, but how should I style the output of individual tags produced by <%= user.tag_list %>?
<%= user.tag_list, :class => 'tags' %> doesn't work...
Note, I want to style the individual results, not the whole block.
Thanks!
This should do the trick:
<% user.tag_list.each do |tag| %>
<span class="tags"><%= tag %></span>
<% end %>