Skip to main content
WordPress made easy with the drag & drop Total WordPress Theme!Learn More

How to Add Multiple Custom Excerpt Lengths In WordPress

Last modified: September 25, 2023

By default WordPress excerpts are set to 55 words and there is an excerpt_length filter which allows you to change this default value to your length of choice. But what if you wanted a different excerpt length on different sections of your site? For example if you are developing a website with multiple post types you may want to show different excerpt lengths depending on the post type. A blog post may have a longer excerpt than for example a portfolio item.

Custom Excerpt Function

Below you will find a custom function I’ve developed to help you display excerpts at different lengths in WordPress. To use the function simply add it to your functions.php file and then you can go about replacing either the_excerpt or the_content functions throughout your theme so you can different excerpt lengths.

/**
 * Returns a custom excerpt with a specific number of words.
 *
 * @link https://www.wpexplorer.com/custom-excerpt-lengths-wordpress/
 * @param array The function arguments.
 */
function wpexplorer_get_post_excerpt( $args = '' ) {
    if ( ! is_array( $args ) ) {
        $args = [
            'length' => $args,
        ];
    }

    // Default arguments.
    $defaults = [
        'post'            => '',
        'length'          => 40,
        'readmore'        => false,
        'readmore_text'   => esc_html__( 'read more', 'textdomain' ) . ' →',
        'custom_excerpts' => true,
    ];

    // Parse arguments, takes the function arguments and combines them with the defaults.
    $args = wp_parse_args( $args, $defaults );

    // Apply filters to the arguments.
    $args = apply_filters( 'wpexplorer_post_excerpt_args', $args );

    // Extract arguments to make it easier to use below.
    extract( $args );

    // Get the current post.
    $post = get_post( $post );

    // Not a valid post.
    if ( ! is_a( $post, 'WP_Post' ) ) {
        return;
    }

    // Get the current post id.
    $post_id = $post->ID;

    // Check for custom excerpts and display them in full without trimming.
    if ( $custom_excerpts && has_excerpt( $post_id ) ) {
        $output = wp_kses_post( $post->post_excerpt );
    }

    // No custom excerpt...so lets generate one.
    else {

        // Generate an excerpt from the post content once shortcodes have been stripped out.
        // Note: If your site is using a shortcode based page builder such as WPBakery you will need
        // to write a complex function to grab the text from the first text block like we do in our Total theme.
        $output = wp_trim_words( strip_shortcodes( $post->post_content ), $length );
    }

    // Add the readmore text to the excerpt if enabled.
    if ( ! empty( $output ) && $readmore ) {
        $output .= '<a href="' . esc_url( get_permalink( $post_id ) ) . '">' . esc_html( $readmore_text ) . '</a>';
    }

    return apply_filters( 'wpexplorer_post_excerpt', $output, $args );
}

How To Use The Function

So now instead of using the_excerpt() in your loops you can use wpexplorer_get_post_excerpt( $args ), where $args is either the number of words you want for your excerpt or an array of arguments to pass to the function.

Basic Example:

Below is a basic example of how to use the function to grab and display an excerpt of 40 words for the current post.

echo wpexplorer_get_post_excerpt( 40 );

Advanced Example:

This is a more advanced example showing how to pass more arguments to the function.

echo wpexplorer_get_post_excerpt( [
    'post'     => 1,    // display excerpt from specific post.
    'length'   => 50,   // only display 50 words.
    'readmore' => true, // enable more links.
] );

Function Filters

You may notice that our snippet includes various apply_filters() functions. Why? The reason for this is if you are working on a premium or free theme or plugin for distribution you will want to give the end users the ability to alter their excerpts via their child theme if needed.

For example if you defined an excerpt to be a certain length for a section of the site the end user could always use the wpexplorer_post_excerpt_args filter to change the excerpt to a different length or customize the read more text.

Using the Custom Excerpt Function with the Gutenberg Excerpt Block

If you are simply using the custom excerpt function inside your theme or plugin then this isn’t a worry, but what if you wanted to also make use of your custom excerpt function for the WordPress excerpt block so that you can have more control over the output?

Luckily it’s very easy to override the excerpt block because it still uses the native get_the_excerpt() function so we can hook into this to override the output. This will of course change the excerpt anywhere get_excerpt() or get_the_excerpt() is used. It won’t specifically target the excerpt block. But for most cases that should be fine and it does keep our code much slimmer.

function wpexplorer_modify_core_excerpt( $excerpt, $post ) {
    return wpexplorer_get_post_excerpt( [
        'post'     => $post,
        'length'   => 25,
        'readmore' => false,
    ] );
}
add_filter( 'get_the_excerpt', 'wpexplorer_modify_core_excerpt', PHP_INT_MAX, 2 );

As you can see we are simply hooking into get_the_excerpt and then returning our own function instead. This will give you way more control over the default excerpts in WordPress including the excerpt block.

Keep in mind that you’ll want to keep the readmore link disabled in this instance because the hook should only return the excerpt text, otherwise you could end up with a double read more link when using the excerpt block.

Creating Better & Custom Excerpts is Easy

As you can see creating custom excerpts in WordPress is quite simple!

Hopefully you’ve found my helper function useful for your project as the default excerpt function in WordPress leaves much to be desired. Being able to display excerpts with different lengths is truly a game changer.

Let me know how you are using the function in the comments below and if you have any questions or suggestions!

27 Comments

  1. keylime

    FAN-TAS-TIC! thanks!

  2. Kakembo Alex

    I use this alot and it works on pages and post, because its a WordPress function so no need of writing another function.

  3. Shua

    Thanks! this is awesome! 🙂

  4. Kursus Web Designur

    My programming skill is so bad. But it help me to adding multiple excerpt 😉
    Thanks so much AJ

  5. lemonthirst

    Thank you,
    life saver as usual!

  6. Michael Hayes

    Thanks for the wp_trim_words tip. Super handy, and new to me.

  7. dcom

    It’s also handy to know that you can control your titles by altering this code. It definitely helps when you only want to show the headline of a title and limit it for the client.

  8. Jonathan

    Helo AJ I’m developing wp theme and iterested if I can use this code snippet in commercial use? Thanks in advance 🙂

    • AJ Clarke

      Definitely any tutorial on my site you can use as you see fit 😉

  9. Jonathan

    ok. many thanks 🙂

  10. Jordan Smith

    You rock dude, thanks!

  11. Jamie Knop

    Thanks for this AJ. I am having an issue with this code though as it wants to remove the image from the very top of the post (not set by featured).

    How can I make it include images also?

    Thanks

    • AJ Clarke

      You can’t Jamie, because the wp_trim_words function strips all HTML. If you have a look at the function in the codex you’ll see that one of the first things the function does is run the content through wp_strip_all_tags.

      • Jamie Knop

        Cheers for clearing that up AJ. Do you know any alternative methods I could use so it would leave the HTML in tact?

        Thanks

        • AJ Clarke

          Not via any core functions, the only alternative I can think of would be using PHP (maybe substr?)

          • Jamie Knop

            Ok cheers anyway AJ. I’m no coder, so I will just carry on playing to see if I can come up with a solution!

  12. jairo

    You are the best!

  13. 1v4n0

    thank yoo. Just what I was looking for. No idea how it works, but who cares 😀

  14. mat

    tnx for this. is it possible to add “read more” link after trimming the text?

  15. Mohsinur Rahman

    It works perfectly. Thankyou for for this interisting posting.

  16. alon188

    Hi there, I have been using this for a while and works great, is there a way to use this function with the get_post function, it does not seem to work when I try to use it, thanks

  17. Alex

    Great Post! Thank you!

  18. Jitender

    Nice Post. Thanks for share..

  19. Peter Johnson

    line 21 should be :
    $args = apply_filters( ‘wpex_get_excerpt_args’, $args );

    • AJ Clarke

      Thanks for the heads up!

  20. Ben

    Thanks for this function, looks like exactly what I need.

    However, I don’t seem to be able to get a ‘read more’ link appear, no matter what combination of arguments I try. I don’t have anything set in the editor side and these are the args I am passing:

    array(
    	'length'          => 80,
    	'readmore'        => true,
    	'readmore_text'   => esc_html__( 'read more', 'textdomain' ),
    	'custom_excerpts' => false,
    	'disable_more'	  => false,
    );
    

    Any help appreciated.

    • AJ Clarke

      If you aren’t seeing the read more link it’s because your post is using a custom excerpt. In the code above custom excerpts are displayed in full so there is no “read more” link because the text won’t be cut off.

      If you want to display a read more link always then just add the code for your link after the code used to output the excerpt. Or you can modify the code above to move readmore link outside of the if/else conditional so it’s always added.

      Edit: I updated the function above so that the read more link is always displayed regardless if it’s a custom excerpt or not. Just keep in mind if it’s a custom excerpt the link may not display “inline” if your custom excerpts automatically have paragraph tags added to them.

Leave a Reply

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

Learn how your comment data is processed by viewing our privacy policy here.