Changing the length of the_excerpt() in Wordpress

How can I change the length of the_excerpt() in Wordpress without editing core files?

Well, first we need to figure out exactly where the excerpt text is truncated. Checking wp-includes/default-filters.php, around line 128 we see:

add_filter('get_the_excerpt', 'wp_trim_excerpt');

Ok, so that’s how it’s cut off. The first step in our fix is to prevent the default function from running and truncating the text at the default length. The easiest way to do this? Simply remove the filter by adding a line to your theme’s functions.php file:

remove_filter('get_the_excerpt', 'wp_trim_excerpt');

Great. So now we’ve got the_excerpt() looking exactly like the_content(). Now we need to create our own pretty little function to handle truncating the_excerpt to the length we need. Since those crazy Wordpress devs have already thought of everything, we’ll use their original function as a template for our new one. The original function can be found in wp-includes/formatting.php, around line 779:

[php]
function wp_trim_excerpt($text) { // Fakes an excerpt if needed
global $post;
if ( ” == $text ) {
$text = get_the_content(”);
$text = apply_filters(’the_content’, $text);
$text = str_replace(’]]>’, ‘]]>’, $text);
$text = strip_tags($text);
$excerpt_length = 55;
$words = explode(’ ‘, $text, $excerpt_length + 1);
if (count($words) > $excerpt_length) {
array_pop($words);
array_push($words, ‘[...]‘);
$text = implode(’ ‘, $words);
}
}
return $text;
}
[/php]

See the line $excerpt_length = 55;? That’s the one we want to change!

Take your new wp_trim_excerpt function and stick it in your theme’s functions.php file. Be sure to rename it to something unique. You should end up with something similar to this:

[php]
function custom_trim_excerpt($text) { // Fakes an excerpt if needed
global $post;
if ( ” == $text ) {
$text = get_the_content(”);
$text = apply_filters(’the_content’, $text);
$text = str_replace(’]]>’, ‘]]>’, $text);
$text = strip_tags($text);
$excerpt_length = 75;
$words = explode(’ ‘, $text, $excerpt_length + 1);
if (count($words) > $excerpt_length) {
array_pop($words);
array_push($words, ‘[...]‘);
$text = implode(’ ‘, $words);
}
}
return $text;
}
[/php]

Note that I only made two changes: 1) renamed the function to “custom_trim_excerpt”, and 2) changed the excerpt_length to 75.

Great, we’re almost there! One step left. Now we have to tell Wordpress to use our new custom function to truncate the_excerpt. We’ll do this by adding a new filter, similar to the one we removed at the very beginning. Stick this line in your theme’s functions.php file:

add_filter('get_the_excerpt', 'custom_trim_excerpt');

Be sure to substitute your new function’s name, assuming you didn’t use the same one I did, and you should be all set!

Note: This guide was written using Wordpress 2.2. The exact procedure may vary with versions, but should be fairly similar.

10 Responses to “Changing the length of the_excerpt() in Wordpress”


  1. 1 Arun

    Nice guide, thanks!

  2. 2 Garry Conn

    Excellent post. I am wondering though, how do you remove the P tag?

  3. 3 Chris Meller

    Garry: All the <p> tags in WordPress are handled by another of the default filters:


    add_filter('comment_text', 'wpautop', 30);

    In order to remove that tag, you’ll need to drop another line in your functions.php file:


    remove_filter('comment_text', 'wpautop');

    But be forewarned - that’ll remove absolutely all of your auto-paragraph formatting. You’ll need to handle all that yourself.

  4. 4 Garry Conn

    Is there a way to make an exception? Meaning, I only need one instance where I need the P tag removed. Can something be written that will remove it only the one spot I need it?

  5. 5 Chris Meller

    Looking back, I realize that I wasn’t paying enough attention when I wrote that earlier comment. Obviously a lack of caffeine if I’ve ever seen one. That should be:


    remove_filter('the_excerpt', 'wpautop');

    I just saw the first wpautop and snagged it, not bothering to look and see that it was for comment text, not post text… Doh!

    Anyway…

    Can something be written? I’m sure it can… Would it be feasible to do so? That depends…

    Only thing I can envision:

    You add your own hook for the_excerpt that runs with a high priority (like first, 0: add_filter('the_excerpt', 'custom_excerpt_no_autop', 0);).

    In that function, essentially, you want to check and see if this post has a custom field you set on that individual post. If that custom field has the value you set (whatever you wanted to use to indicate not to auto-p this post), you run your remove_filter('the_excerpt', 'wpautop'); and the post is left alone.

    In actual practice, I’m not sure how well this would work out, or how it would affect any excerpts coming after this post. You may actually need to hook again with very low priority and re-add the default wpautop rule.

    I’d probably try to find another way… Like fixing the actual issue: that auto-p’ing is causing that big of a problem.

  6. 6 Garry Conn

    Can I create another instruction that give a special set of instruction for the excerpt where I want to use it uniquely just once without the P tag?

    Sort of like in CSS you can tell H1 to be really big but only when it is found in the header, and then you can tell H1 to be smaller in the content or post sections.

    So can something be written like this:

    If the php excerpt code is found here then remove the P tag; however, if the php excerpt code is found everywhere else keep the P tag.

  7. 7 Chris Meller

    The only other option I see would be a modification of what I suggested earlier. You basically substitute the portion where you check to see if there’s a custom field with your skip value with the part where you check to see what the other contents of the post are… Either way, the rest of the brutal hack remains…

  8. 8 Nic Johnson

    Works like a charm. Thanks for sharing!

  9. 9 Chris Meller

    Glad I could help, Nic!

  10. 10 Sebastian

    complete code for wp 2.3 / template functions.php

    // Excerptfunktion aus p-includes/default-filters.php ausser Kraft setzen
    remove_filter(’get_the_excerpt’, ‘wp_trim_excerpt’);

    // Neue Excerptfunktion aktivieren
    add_filter(’get_the_excerpt’, ‘modifiziert_wp_trim_excerpt’);

    // Excerpt kürzen
    function modifiziert_wp_trim_excerpt($text) { // Fakes an excerpt if needed
    global $post;
    if ( ” == $text ) {
    $text = get_the_content(”);
    $text = apply_filters(’the_content’, $text);
    $text = str_replace(’]]>’, ‘]]>’, $text);
    $text = strip_tags($text);
    $excerpt_length = 45;
    $words = explode(’ ‘, $text, $excerpt_length + 1);
    if (count($words) > $excerpt_length) {
    array_pop($words);
    array_push($words, ‘…’);
    $text = implode(’ ‘, $words);
    }
    }
    return $text;
    }

Leave a Reply