10

I'm quite long description that I want to truncate using truncate helper. So i'm using the:

truncate article.description, :length => 200, :omission => ' ...'

The problem is that I want to use more as a clickable link so in theory I could use this:

truncate article.description, :length => 200, :omission => "... #{link_to('[more]', articles_path(article)}"

Omission text is handled as unsafe so it's escaped. I tried to make it html_safe but it didn't work, instead of link [more] my browser is still showing the html for that link.

Is there any way to force truncate to print omission link instead of omission text?

Jakub Troszok
  • 99,267
  • 11
  • 41
  • 53
  • 1
    possible duplicate of [Make omission in ruby truncate a link](http://stackoverflow.com/questions/4964073/make-omission-in-ruby-truncate-a-link) – Simone Carletti Feb 17 '11 at 20:14

7 Answers7

11

With Rails 4, you can/should pass in a block for the link:

truncate("Once upon a time in a world far far away", 
  length: 10, 
  separator: ' ', 
  omission: '... ') {     
    link_to "Read more", "#" 
}
Adam Rubin
  • 777
  • 1
  • 7
  • 16
11

I would suggest doing this on your own in a helper method, that way you'll have a little more control over the output as well:

def article_description article
  output = h truncate(article.description, length: 200, omission: '...')
  output += link_to('[more]', article_path(article)) if article.description.size > 200
  output.html_safe
end
Patrick
  • 1,410
  • 2
  • 19
  • 37
Pan Thomakos
  • 34,082
  • 9
  • 88
  • 85
7

Dirty solution... use the method "raw" to unescape it.
you have to be sure of "sanity" of your content.

raw(truncate article.description, :length => 200, :omission => "... #{link_to('[more]', articles_path(article)}")

raw is a helper acting like html_safe .
bye

edit: is not the omission of being escaped , but the result of truncate method.

andrea
  • 3,515
  • 2
  • 22
  • 14
4

I encountered a similar situation and this did the trick. Try (line breaks for readability):

(truncate h(article.description), 
                  :length => 200, 
                  :omission => "... #{link_to('[more]',articles_path(article)}")
                  .html_safe

You can use h to ensure sanity of article description, and since you are setting the link_to to a path you know to not be something potentially nefarious, you can mark the resulting string as html_safe without concern.

saneshark
  • 1,243
  • 13
  • 25
  • You'll need to be careful to pass in `escape: false`, at least as of Rails 4.0.1, since [`TextHelper#truncate` will add its own escaping](https://github.com/rails/rails/blob/58ab79ff9b34c22c3477e29763fdd4f4612e938d/actionpack/lib/action_view/helpers/text_helper.rb#L92) to the concatenation of `h(article.description)` and the `omission` text. No amount of `.html_safe` will prevent it. – Adam Prescott Nov 25 '13 at 19:04
2

TextHelper#truncate has a block form of truncate, which lets you use a link_to that isn't escaped, while still escaping the truncated text:

truncate("<script>alert('hello world')</script>") { link_to "Read More", "#" }

#=> &lt;script&gt;alert(&#39;hello world&#39;...<a href="#">Read More</a>
Adam Prescott
  • 1,145
  • 2
  • 11
  • 17
1

The only one that worked for me :

<%= truncate(@article.content, length: 200, omission: " ... %s") % link_to('read more', article_path(@article)) %>
Noémien Kocher
  • 1,324
  • 15
  • 17
1

I had the same problem, in my case i just used :escape => false. That worked:

truncate article.description, :length => 200, :omission => "... #{link_to('[more]', articles_path(article)}", :escape => false

From documentation :

The result is marked as HTML-safe, but it is escaped by default, unless :escape is false.... link: http://apidock.com/rails/ActionView/Helpers/TextHelper/truncate

kroteDev
  • 71
  • 1
  • 3