Pen resting on a book, by Aaron Burden

Excerpt is an optional text associated to a post. Most of the time, it is used as the post summary. If you are using the new editor, you will see that there is an option in the sidebar called Excerpt:

Excerpts in Gutenberg
Excerpts in Gutenberg.

If it doesn’t show up, you may have to enable the option from Gutenberg’s settings. Click on the ellipsis icon in the upper right corner of the editor and then Options:

Gutenberg settings
Gutenberg settings.

Then look for Excerpt and enable it:

How to activate the panel to edit the excerpt of a post.
How to activate the panel to edit the excerpt of a post.

Depending on how your theme is configured, the excerpt will show up when looking at your posts in the blog, the results of a search, etc. For example, on our blog you can see how all our posts are presented with their related excerpts:

Posts in Nelio's blog with their excerpts.
Posts in Nelio’s blog with their excerpts.

Now, is it always mandatory to write this excerpt? If we don’t, what does WordPress do? Does it show something or nothing at all? Well, we are going to answer these questions and we’ll take a closer look at the options WordPress gives us customize excerpts.

How WordPress Excerpts Work

WordPress has two functions to obtain a post’s excerpt: get_the_excerpt and the_excerpt. Both are defined in wp-includes/post-template.php and if you take a look at their source code you will discover that all the_excerpt does is echo the result of get_the_excerpt (after filtering it with the_excerpt). So, essentially, we can roughly say that the only thing you need to understand to know how excerpts work in WordPress is the get_the_excerpt function.

As you can see, get_the_excerpt is extremely simple:

function get_the_excerpt( $post = null ) {
  // ...
  $post = get_post( $post );
  if ( empty( $post ) ) {
    return '';
  }
  // ...
  return apply_filters( 'get_the_excerpt', $post->post_excerpt, $post );
}

Basically, it loads a post (if you don’t set one, it uses the post available in the WordPress loop) and returns its post_excerpt attribute. So it seems that no excerpt means WordPress won’t show anything in the end, right?

Not so fast, buddy.

Note that this function doesn’t actually return the value of post_excerpt directly. Instead, it filters it using a new filter: get_the_excerpt. So if there are any actions associated with that filter, the final result can potentially change and no longer be the empty string…

And indeed, that’s what’s happening here! If we don’t write an excerpt for a given post, this is what we’ll see in the front-end:

Automatic excerpt.
Automatic excerpt generated by WordPress.

the first words of our post will be the excerpt WordPress generates.

The wp_trim_excerpt Function

If we perform a quick search in the WordPress source code we will see that, by default, there is only a single action associated with the get_the_excerpt filter. Specifically, in wp-includes/default-filters.php we see that a function named wp_trim_excerpt is hooked.

According to WordPress docs, wp_trim_excerpt is responsible for generating an excerpt with a maximum of 55 words and an ellipsis appended if necessary. And here is the key: the function considers that generating an excerpt “is necessary” if there isn’t one already (which, in general, is equivalent to saying that the user has not written the excerpt in the editor). You can see this in the source code of the function :

function wp_trim_excerpt( $text = '', $post = null ) {
  $raw_excerpt = $text;
  if ( '' == $text ) {
    $post = get_post( $post );
    $text = get_the_content( '', false, $post );
    // [...] » Generates the excerpt using the post content
  }
  return apply_filters( 'wp_trim_excerpt', $text, $raw_excerpt );
}

See? If there is no excerpt ($text is the empty string), then retrieve the content of the current post(get_the_content from $post) and use it to generate an excerpt.

From this point on, you can keep digging and discover how WordPress actually generates the source code. However, I think you already got the idea, so let’s take a look at the documentation again, as it sheds some light on this topic:

Returns a maximum of 55 words with an ellipsis appended if necessary. The 55 word limit can be modified by plugins/themes using the excerpt_length filter. The ‘ […]’ string can be modified by plugins/themes using the excerpt_more filter.

wp_trim_excerpt Documentation

So now you know everything there is to know to fully customize the automatic excerpts WordPress generates for your posts.

How to Customize Automatic Excerpts

Let’s take a look at some examples of how we can use the filters we’ve seen throughout today’s post to customize automatic excerpts. By the way, remember that in order to add any of these modifications to your website you probably need to create a plugin.

a) How to change the number of words I want in my excerpts

This is one of the simplest. We have already seen that we have at our disposal the excerpt_length filter to choose how many words we want in our excerpts, so let’s use it:

function nelio_100_word_excerpts( $length ) {
  if ( is_admin() ) {
    return $length;
  }
  return 100;
}
add_filter( 'excerpt_length', 'nelio_100_word_excerpts', 99 );

Notice that the first thing we do in our function is to make sure we’re in the front-end. If we are on the Dashboard (is_admin), we better not do anything with our excerpts. Once we’re sure we’re in a “safe environment,” we just need to return our magic number. In my case: 100 words.

b) How to change the text that appears after an automatic extract

This one’s also extremely easy because we have already seen that there is a filter for it:

function nelio_clickable_read_more( $more ) {
  if ( is_admin() ) {
    return $more;
  }
  return sprintf(
    '<a href="%s">Tell me more!</a>',
    esc_url( get_the_permalink() )
  );
}
add_filter( 'excerpt_more', 'nelio_clickable_read_more', 99 );

In this case, all we do is return the text “Tell me more!” after the summary and make it a link so that users can click on it.

c) How to limit the length of an excerpt to a certain number of characters

The wp_trim_words function has a filter with the same name that we can use to modify the final excerpt that WordPress uses. So let’s use it:

function nelio_140_char_excerpts( $excerpt, $raw_excerpt ) {
  if ( is_admin() ) {
    return $excerpt;
  }
  if ( '' !== $raw_excerpt ) {
    return $excerpt;
  }
  return mb_substr( $excerpt, 0, 140 );
}
add_filter( 'wp_trim_excerpt', 'nelio_140_char_excerpts', 99, 2 );

The wp_trim_words filter applies to both automatic and user-defined excerpts. In my example, I am only interested in modifying excerpts that have been generated automatically, so I need to add a new condition. If you remember, wp_trim_words only generates an automatic excerpt if the original excerpt was empty, so all you have to do is check this to get the desired result.

On the other hand, notice I used mb_substr instead of the classic substr function. If you’re wondering why, the reason is simple: if you write in your blog in a language other than English, you’ll likely be using multi-byte characters, and shortening multi-byte strings with substr can go wrong. Read the PHP documentation for more info on this.

d) How to create excerpts with the first paragraph of the content

And finally, an example of how to create an excerpt using exactly the first paragraph of your post. No explanation this time, so pay attention to what I’m doing:

function nelio_first_paragraph_excerpts( $excerpt, $raw_excerpt ) {
  if ( is_admin() ) {
    return $excerpt;
  }
  if ( '' !== $raw_excerpt ) {
    return $excerpt;
  }
  $content = apply_filters( 'the_content', get_the_content() );
  return substr( $content, 0, strpos( $content, '</p>' ) + 4 );
}
add_filter( 'wp_trim_excerpt', 'nelio_first_paragraph_excerpts', 99, 2 );

In short…

The great power of WordPress lies in its extensibility. Today we have seen in detail how WordPress generates post excerpts and all the filters and functions it offers to customize the final result to your needs.

I hope you liked today’s post. Share it with your friends so that more people know the advantages of WordPress!

Featured image by Aaron Burden on Unsplash.

18 responses to “How to Create and Customize WordPress Excerpts”

  1. sneha Avatar
    sneha

    Nice info..help me a lot.!
    i want that wordpress excerpt filter first blockquote tag anywhere in the whole post.
    please help.

    1. David Aguilera Avatar

      Hi! Thanks. Can you please rephrase your question? I don’t understand what you mean…

  2. Kisanu Mistry Avatar
    Kisanu Mistry

    Can u pls tell me what is wrong with this excerpt code for wordpress. // Excerpt Function

    function excerpt($num) {

    $limit = $num+1;

    $excerpt = explode(‘ ‘, get_the_excerpt(), $limit);

    array_pop($excerpt);

    $excerpt = implode(” “,$excerpt).” <a>ID) .” ‘ class=’”.readmore.”‘>Continue Reading »“;

    echo $excerpt;

    }
    when i am using this it’s showing- Warning: Use of undefined constant readmore – assumed ‘readmore’ (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\learningwp\wp-content\themes\mytheme\functions.php on line 71.
    how do can fix the problem.

    1. David Aguilera Avatar

      Right before the echo, you try to concatenate the string class=' with something named readmore. If that’s a variable, it should be $readmore, but it doesn’t look like you defined it anywhere, so I guess it’s not. You probably need to type in <a href='...' class='readmore'>Continue Reading »</a>.

  3. Doug Brown Avatar
    Doug Brown

    Would you know how to force these new excerpts to be used as meta descriptions too?

    1. David Aguilera Avatar

      It depends on the SEO plugin you’re using, as that’s the one that’s probably generating the meta description tag. For example, if I recall correctly, Yoast SEO uses wpseo_metadesc to filter meta descriptions.

  4. Mark Avatar
    Mark

    I have been struggling to find a solution, I want to set where and excerpt starts for example after the first 10 words, is that something that is possible?

    The reason I ask is I have the word Summary at the start of every post, buttons with text that are appearing in the Excerpt and the title of the page appearing as well.

    Thank you so much for your help.

    1. David Aguilera Avatar

      Sure. You simply need to use a filter named the_excerpt. This filter uses one single argument, an excerpt, which is a string (i.e. some “text”). Using PHP functions like substr, you can get rid of the first n characters.

      BTW, if you’re interested in removing the first n words, you can simply split your string into words (using PHP’s explode function with the space character as its delimiter), remove the first n elements of the array (which, incidentally, are the first n words), and then rejoin the remaining elements into one single string (using PHP’s implode function).

  5. Kasper Avatar
    Kasper

    Hi there, thanks for your helpful article. Do you know if there’s a way to create the excerpt from an ID? I have a text block in my post, from which i would like to create the excerpt. But after a lot of trying, i’m stuck.

    Hope you can help me. Thanks in advance.

    1. David Aguilera Avatar

      There’s the function get_the_excerpt that takes an optional post ID as a parameter. So all you need to do to generate the excerpt from an ID is to use it: get_the_excerpt(32) would give you the excerpt associated to post 32.

      1. Kasper Avatar
        Kasper

        That’s almost where i’m looking for. But i’m trying to create the excerpt from a specific (div) ID inside the post, so not from the post-ID. I have multiple elements inside my most, but i want to create the excerpt from a specific ID, which is after some other elements. Is this also possible?

        1. David Aguilera Avatar

          Oh, I get it. You mean you want to use part of your post content as your excerpt – in particular, a bit of content wrapped on a div with a certain ID 🙂

          Well, my post already explains how to use the filter get_the_excerpt to generate the excerpt you want. This filter takes two arguments: the “original” excerpt (which you’ll ignore) and the post object. This object contains an attribute named post_content with, well, the content of your post. All you need to do is use PHP’s DOMDocument class to load the post_content in a DOM and then use the function getElementById to retrieve the DOMElement that contains what will become your excerpt and finally access its attribute $textContent.

          1. Kasper Avatar
            Kasper

            That’s exactly what I mean. So this must be the solution I was looking for. I will try it this way. Thanks a lot, you’re a hero!

  6. Faruk Avatar
    Faruk

    Hi,
    Thanks for the great info.
    My problem is slightly different.
    I already have the function as seen below but I also want to ad “.. read more” tect instead of just currently displaying “…” at the end of the excerpt text. Can you please help?
    Here is the function I am using.

    1. David Aguilera Avatar

      Looks like WordPress got rid of your function. Anyhow, it’s actually quite easy. Instead of appending this variable to your trimmed excerpt:

      $more = '...';

      append this one:

      $more = sprintf( ' <a href="%s" rel="nofollow ugc">%s</a>', get_the_permalink(), '[read more]' );

      In other words, you’re basically generating a small link tag with the correct URL and the text you want.

  7. Malik Avatar
    Malik

    Not properly working in Oxygen Builder, do you have any solution for that, please?

    1. David Aguilera Avatar

      You mean that get_the_content doesn’t work as expected? That’s weird. You can ask Oxygen Builder’s support team how you can retrieve the text content of a page built with their builder and then use that to generate the excerpt. Other than that, I’m afraid I don’t know what to do.

Leave a Reply

Your email address will not be published. Required fields are marked *