jay
jay

Reputation: 12495

Rails Truncate Method: Ignore html in a string in Length Count

I use a truncate method to truncate a string in my site. I truncate with the code:

 truncate(auto_link(textilize(post.content)), :length  => 140)

This truncation truncates the post content, but there is a problem with the content contains links. EG the post content is:

 <p>Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo 
 <a href="http://www.yahoo.com">Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo 
 Yahoo </a> Google Google Google Google Google Google Google Google Google Google  <a 
 href="http://www.google.com"> Google Google Google Google Google Google Google Google 
 </a><br></p>

In this case, the all the html tags and the links get counted in the character count by truncate method, rather than the truncate method counting the characters that a viewer would actually see:

 Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo
 Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo Yahoo  (etc..)

Is there any work around here for the truncation method?

EDIT: new example to clear up ambiguities:

Users post their posts in plain text, and are allow to use textile for some formatting. In terms of posting links, I allow users to (a) paste plain urls (http://www.site.com, www.site.com, etc..), (b) use textile syntax which converts "the click me text":http://www.example.com to the click me text or take their time to embed links in html form.

I want a page that has snippets of a person's posts to show only the first, say, 140 characters of their post. But I want this to be 140 characters of the text that a reader would see. In other words, let's say a user's post starts as:

 Today I went to the market to pick up some fruit. "At the market there was this awesome
 fruit display!":http://www.externalsite.com/picture.jpg Definitely want to go back 
 tomorrow!

This will be converted by textilize to a string of 193 characters:

 Today I went to the market to pick up some fruit. <a href="http://www.externalsite.com/picture.jpg"> 
 At the market there was this awesome fruit display!</a> Definitely want to go back 
 tomorrow!

The text the user will see on a page is only 138 characters:

 Today I went to the market to pick up some fruit. At the market there was this awesome
 fruit display! Definitely want to go back tomorrow!

The 193 character long text would be truncated by truncate, but if I had a work around the whole text would display, ending up appearing as just 138 characters with the link embedded.

Upvotes: 1

Views: 1969

Answers (3)

jay
jay

Reputation: 12495

For those interested, to get an accurate count without links, one can do:

 count = strip_tags(string).count

(This is for a string that has html tags in it. If the string needs to be 'textilized' etc.. first, then the code is count = strip_tags(textilize(string)).count).

Rather than use truncate, I just limited the count to 140 characters of this true count ie switched this to a validation on the field.

Upvotes: 0

Simone Carletti
Simone Carletti

Reputation: 176382

It's not a good idea to truncate a text containing HTML code.

I suggest you to use plain text. Otherwise, an alternative would be

  1. use auto_link
  2. replace every link with a 1 char placeholder, example $
  3. truncate
  4. replace back every placeholder with the old corresponding link

It's a kind of a hack, but it should work. Again, I suggest you to use plain text when you truncate.

Upvotes: 0

pdu
pdu

Reputation: 10413

You're returning a string with all the links in it. So truncate does it right. What you need is to pass things through a method which only gives you back the text that is linked (which should be truncated, I guess).

You could use a RegEx for this to get the linked string, e.g. (not tested)

post.content.gsub /<a[\w\"]*>([a-z]*)<\/a>/i do |link_text|
  truncate(auto_link(link_text), :truncate => 40)
end

Upvotes: 0

Related Questions