Last week I came across a pretty solid problem, by the time I found the most appropriate solution it had evolved quite a bit. I felt it had the making for a worthwhile blog post, so here it goes.
The problem: we need to display only the first 220 characters of the body of a Press article on the Press Index page.
Initial solution: implement Rails truncate helper. It can be used in the view, as such:
truncate(press.description, length: 220)
This worked for the first 9 items on the page, running as a standard
press_serializer.rb file that looks like this:
def description object.description.truncate(220) end
That all worked, but didn’t render well with the other styles on the page, was showing some markup tags, and isn’t the most efficient solution. So, I moved the nuts and bolts from the view to the
application_helper.rb and made it into a method:
def truncate_description(description) description.truncate(220).html_safe end
So now in the view it looks like this:
I also modified the method in the serializer for the html template to this:
def description object.description.truncate(220).html_safe end
It’s definitely cleaner code in the view file, and its faster coming from the application helper.
Note that the
.html_safe is necessary because we are using a WYSIWYG (What You See Is What You Get) editor to create the description, so there are potentially a lot of opening and closing of tags.
This all worked in our QA and the clients. The first 9 records were being produced via the
each loop, and all the rest with the JSON and HTML template. But, as it so happened, we came across an edge case, and that was my problem to solve.
New problem: Basically, what was happening was that the clients wrote a description and included a link within the first 220 characters, which was cut off by the
truncate helper. This meant that there was a tag that wasn’t closing, and it bled the link content onto the first piece of text in the next description card.
What would have been super easy was just to tell the clients to rewrite the article, and move the link. Oh, and in the future, don’t put a link within the first 220 characters, thanks! But, of course, that’s not an option. The solution seems like an obvious one, even to me as a write this, but it actually took a good bit of googling to find it.
truncate_html gem to Gemfile
truncate_html in the view
It can be as simple as that, but to add some versatility I also created a
truncate_html.rb file in my
TruncateHtml.configure do |config| config.length = 220 end
The length could have been added to the line in the view file, but it’s cleaner to have the initializer file, and allows for growth, should any other parameters be necessary.
As for the JSON and HTML templates, after I installed
html-truncate I just had to two variables to the top of the HTML template file:
var truncate = require('html-truncate');
let description = truncate(press.description, 220);
Now both the Ruby gem and JS package will close any open tags before truncating, allowing for there to be links, bold tags, or whatever at any place in the description with no problem at all.