Rails truncate helper with link as omit text - ruby-on-rails

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?

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

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", "#"
}

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.

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.

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", "#" }
#=> <script>alert('hello world'...Read More

The only one that worked for me :
<%= truncate(#article.content, length: 200, omission: " ... %s") % link_to('read more', article_path(#article)) %>

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

Related

Truncate & Simple Format String in Ruby on Rails

I am trying to take a string and render it with simple_format while at the same time truncating it. It works when I just use one or the other, but not when I do both. Why is this not doing simple_format and truncating simultaneously.
Controller
myString = "Apple’s New Laptop"
View
<%= simple_format truncate( myString, :length => 20 ) %>
The way to do this is to truncate after you have used simple_format on the string. Since truncate escapes the string by default, you have to use the escape: false option.
> myString = "Apple’s New Laptop"
> truncate(simple_format(myString), escape: false)
> => "<p>Apple’s New Laptop..."
> truncate(simple_format(myString), escape: false, length: 19)
> => "<p>Apple’s..."
This has the potential to create unbalanced HTML tags by cutting the </p> for example, so use carefully.
There was something changed in the truncate-helper in Rails 4.
The documentation does tells us:
The result is marked as HTML-safe, but it is escaped by default, unless :escape is false.
http://apidock.com/rails/v4.0.2/ActionView/Helpers/TextHelper/truncate
Rails normally escapes all strings. If you just want to put some unicode chars in strings in your code, you can do it by using the \u notation with the hexadecimal code. Then truncate will also count the char as exactly one char.
myString = "Apple\u2019s New Laptop"
This might be late but useful to someone else. This worked for me.
<%= truncate(myString, escape: false, length: 20 ) %>

Ruby on Rails, trim the text

Why this code is not work?
<%= truncate(post.text, :length => post.text.rindex(".", 500)) %>
I need to trim the text on last dot before 500th symbol.
Use the :separator option. It will truncate at the dot before 500 characters
truncate(post.text, :length => 500, :separator => '.')

HTML_SAFE allow everything except <span style="font-size: TAG

How do I disallow font size change in html_safe rails 3
I have here a truncated description of an article, and I want to disallow big font sizes in display mode when the user inputs a big font size using tinymce editor
= truncate(event.description.html_safe, :length => 110, :omission => "...")
How can i do that?
You will want to use the sanitize helper before marking it as html_safe. Unfortunately for you, in this case, the blacklist functionality has been removed, so you will need to list literally all of the attributes you do want, in addition to the defaults. It may be easier to use a regex to remove the attribute in question.
Also, for what it's worth, raw(event.description) does the same as event.description.html_safe, but will not blow up on a nil value (not sure what your validation rules are), so it is generally preferred.
Edit:
Sanitize example usage (from http://apidock.com/rails/v3.2.8/ActionView/Helpers/SanitizeHelper/sanitize ):
truncate( raw( sanitize(event.description, :tags => %w(table tr td), :attributes => %w(id class style) ) ), :length => 110, :omission => "...")
Note: Truncating HTML like that can lead to some weird and hard-to-track-down errors, by creating invalid HTML because of cut-off end tags.

Ruby & Rails: Variable in string

This is my code and it is loaded in a helper-class
output += '<button class="del_account" param-del="{account.id}">delete</button>'
When I render this to html, account.id is just converted to a string. And not the 'id' that I need. How can I solve this? Because this isn't working either.
output += '<button class="del_account" param-del="#{account.id}">delete</button>'
or this
output += '<button class="del_account" param-del="' +account.id +'">delete</button>'
thanks for your help.
If you need to use both " and ' symbols then here is simple way to deal with them:
output += %[<button class="del_account" param-del="#{account.id}">delete</button>]
This way you can safely place any of mentioned symbols without worrying to escape them.
You could use the Rails helper method content_tag (documentation) which makes things a bit cleaner and more readable.
output += content_tag(:button, "delete", :class => "del_account", :'param-del' => account.id)
Also, technically 'param-del' makes your HTML invalid - your custom attributes should begin with 'data-', so updating above would become:
output += content_tag(:button, "delete", :class => "del_account", :'data-account-id' => account.id)

Displaying Only the first x words of a string in rails

<%= message.content %>
I can display a message like this, but in some situations I would like to display only the first 5 words of the string and then show an ellipsis (...)
In rails 4.2 you can use truncate_words.
'Once upon a time in a world far far away'.truncate_words(4)
=> "Once upon a time..."
you can use truncate to limit length of string
truncate("Once upon a time in a world far far away", :length => 17, :separator => ' ')
# => "Once upon a..."
with given space separator it won't cut your words.
If you want exactly 5 words you can do something like this
class String
def words_limit(limit)
string_arr = self.split(' ')
string_arr.count > limit ? "#{string_arr[0..(limit-1)].join(' ')}..." : self
end
end
text = "aa bb cc dd ee ff"
p text.words_limit(3)
# => aa bb cc...
Try the following:
'this is a line of some words'.split[0..3].join(' ')
=> "this is a line"
# Message helper
def content_excerpt(c)
return unlessc
c.split(" ")[0..4].join + "..."
end
# View
<%= message.content_excerpt %>
But the common way is truncate method
# Message helper
def content_excerpt(c)
return unless c
truncate(c, :length => 20)
end

Resources