Show relevant chunks of text with Rails `excerpt` helper
Tags: ruby, rails, webdev
Published: 2021-02-12 15:06:10

---
title: Show relevant chunks of text with Rails `excerpt` helper
published: true
date: 2021-02-12 13:00:00 UTC
tags: ruby,rails,webdev
canonical_url: https://boringrails.com/tips/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:

![](https://boringrails.com/images/excerpt-example.png)

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.

<meta data-controller="callout" data-callout-text-value="&lt;%= excerpt(email.body.to_plain_text, params[:q], radius: 15) %&gt;">

```erb
<%= 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](https://boringrails.com/tips/rails-highlight-search-results)!

## Options

```ruby
@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:

```ruby
@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`.

```ruby
@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.

```ruby
@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](https://edgeapi.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-excerpt)

Rails API Docs: [ActionText#to\_plain\_text](https://edgeapi.rubyonrails.org/classes/ActionText/RichText.html#method-i-to_plain_text)

* * *
[![](https://boringrails.com/images/twitter-banner.png)](https://twitter.com/_swanson)