Tip: Show relevant chunks of text with Rails `excerpt` helper
The Rails helper excerpt
can extract a chunk of text that matches a certain phrase, no matter where in the string it is.
Imagine you wanted to display a list of emails matching a certain search term:
Simply filter down your records and then use excerpt
on the email body.
Usage
Here’s what your view might look like to build this feature.
<%= link_to email do %>
<div class="flex justify-between items-center">
<p class="text-sm font-medium text-gray-900">
<%= email.sender_name %>
</p>
<%= local_time_ago email.received_at %>
</div>
<p class="text-sm text-gray-700">
<%= email.subject %>
</p>
<p class="text-sm text-gray-500">
<%= excerpt(email.body.to_plain_text, params[:q], radius: 15) %>
</p>
<% end %>
One trick is that if you are using ActionText
, call to_plain_text
otherwise you might end up with unclosed HTML tags. In general, when you show an excerpt of rich text, you don’t want all of the formatting to be applied anyways.
For bonus points, combine with the Rails highlight helper!
Options
@product.description = "A one-of-a-kind vintange DHH coffee mug signed by the man himself!"
excerpt(@product.description, "coffee", radius: 10)
=> "...tange DHH coffee mug signe..."
This helper is case-insensitive and can accept a string or Regex:
@product.description = "A one-of-a-kind vintange DHH coffee mug signed by the man himself!"
excerpt(@product.description, "COFFEE", radius: 10)
=> "...tange DHH coffee mug signe..."
excerpt(@product.description, /tea|coffee/, radius: 10)
=> "...tange DHH coffee mug signe..."
Options
You can expand the “radius” – or how many characters around the match – are shown. The default is 100
.
@product.description = "A one-of-a-kind vintange DHH coffee mug signed by the man himself!"
excerpt(@product.description, "coffee", radius: 5)
=> "...DHH coffee mug..."
excerpt(@product.description, "coffee", radius: 25)
=> "...e-of-a-kind vintange DHH coffee mug signed by the man hi..."
If you need to change the ...
into something else, use the omission
option.
@product.description = "A one-of-a-kind vintange DHH coffee mug signed by the man himself!"
excerpt(@product.description, "coffee", radius: 10)
=> "...tange DHH coffee mug signe..."
excerpt(@product.description, "coffee", radius: 10, omission: "---")
=> "---tange DHH coffee mug signe---"
excerpt(@product.description, "coffee", radius: 10, omission: "<snip>")
=> "<snip>tange DHH coffee mug signe<snip>"
Additional Resources
Rails API Docs: TextHelper#excerpt
Rails API Docs: ActionText#to_plain_text