Manage Multiple Excerpt Lengths

WordPress-Christmas-10Behind our 10th door of our Advent Calendar, we have a tip how to use multiple excerpt lengths. WordPress 2.9 allows you via filter to adjust excerpt more string and the length of the excerpt. But if you need several excerpt lengths for different templates, then what?

Suppose we even need an excerpt of 30 words, and once with 45 words and "..." as more string.
First, we write the filter functions with the required values.

function wpe_excerptlength_teaser( $length ) {
    
    return 45;
}
function wpe_excerptlength_index( $length ) {
    
    return 30;
}
function wpe_excerptmore( $more ) {
    
    return '...';
}

Now the new excerpt function.

function wpe_excerpt( $length_callback = '', $more_callback = '' ) {
    
    if ( function_exists( $length_callback ) )
        add_filter( 'excerpt_length', $length_callback );
    
    if ( function_exists( $more_callback ) )
        add_filter( 'excerpt_more', $more_callback );
    
    $output = get_the_excerpt();
    $output = apply_filters( 'wptexturize', $output );
    $output = apply_filters( 'convert_chars', $output );
    $output = '<p>' . $output . '</p>'; // maybe wpautop( $foo, $br )
    echo $output;
}

This function will be given the two filter functions. It will examine whether those features are available and if so, we applied the filter. Isn't there a length function, then WordPress applies the default value of 55 words. Thereafter, the excerpt will be taken. Then additional filters are applied (see default_filters.php). I haven't used the filter convert_smilies, it doesn't work with automatic excerpts anyways and I personally do not like wpautop because it comes with unpredictable results, especially in lists or code. That's why I wrapp the outputs with a clause.

Now we need the function in the template.

<?php wpe_excerpt('wpe_excerptlength_index', 'wpe_excerptmore'); ?>
// the other one
<?php wpe_excerpt('wpe_excerptlength_teaser', 'wpe_excerptmore'); ?>

Now, it makes no sense to write for any value of 1-55, a filter function ;), but for 2-3 different values in different views, the solution is useful.

Comments are closed.

21 comments

  1. Oliver Schlöbe

    Very nice. Thanks guys! :)

  2. paul

    that all seems like alot of work for such a simple task. i started off using the_excerpt_rereloaded() but then wrote myown as its so easy to make custom length strings within wordpress,

    function my_excerpt($excerpt = '', $excerpt_length = 50, $readmore = "Continue Reading »",$tags = '<a>') {
    	global $post;	
    	$string_check = explode(' ', $excerpt);
    		
    	if (count($string_check, COUNT_RECURSIVE) > $excerpt_length) :
    		$new_excerpt_words = explode(' ', $excerpt, $excerpt_length+1); 
    		array_pop($new_excerpt_words);
    		$excerpt_text = implode(' ', $new_excerpt_words); 
    		$temp_content = strip_tags($excerpt_text, $tags);
    		$short_content = preg_replace('`\[[^\]]*\]`','',$temp_content);
    		$short_content .= ' ... <a>'guid .'" title="'.$post->post_title.'">'.$readmore.'</a>';
    		return $short_content;		
    } 
    echo my_excerpt(get_the_content(), 30);
    echo my_excerpt(get_the_content(), 50);
    echo my_excerpt($your_content, 30);

  3. James

    Long time reader... first time posting ;)

    Just wanted to say I'm enjoying and learning a ton from this series. Keep up the great work!

    I just need for wordpress 2.9 to go ahead and get pushed out the door so I can begin playing [breaking] it and the new capabilities it provides. Know any good tutorials for setting up wp/wpmu with svn?

    Thanks again!

    -james

  4. Michael

    Danke Oliver, ich tue mein Bestes ;)

    @James: You are welcome!
    Sorry, but i can't help you with a svn tutorial.

  5. Bloody

    Thanks Michael ! ;)

    To manage my 5 excerpt lengths in different templates, I'm enjoy to have found your great solution. :)

  6. Dian

    Didn't worked for me?

    What do I do wrong?

    First two pieces of code went into my functions.php then the third goes into the template file?

  7. Steve

    Thanks for the snippet, really useful!

    Dian, what theme are you using, are there any existing functions that modify the excerpt that might be conflicting?

  8. Denise

    great function. solves a big problem for me. is there any way to keep the line breaks that are in the post in the excerpt as it is pulled with this function? i notice that when one manually puts the excerpt in in WP 3.0, the line breaks come with.

    thanks again. this is great stuff.

  9. Sam

    Great article, was easy to understand the function, I customised this to simply use the default the_excerpt, changing the default length, then simply adding 1 new custom excerpt function (wp_custom_excerpt) which was 100 chars.

    function wp_longerexcerpt($length) {
    return 100;
    }

    function wp_custom_excerpt($length_callback='', $more_callback='') {
    global $post;
    if(function_exists($length_callback)){
    add_filter('excerpt_length', $length_callback);
    }
    $output = get_the_excerpt();
    $output = apply_filters('wptexturize', $output);
    $output = apply_filters('convert_chars', $output);
    $output = ''.$output.'';
    echo $output;
    }

    thanks!

  10. Sbobet

    Thanks michael ;)

    need to costum excerpth lenght for sidebar and related post under loop.

  11. Keri

    Yay! Works perfectly. Thanks so much! =)

  12. Michael

    I have this working, except for the more string? It's not a link, it's just a string. I tried adding the_permalink() to it, but it didn't like it.

    Does this not return more string as a link?

  13. Michael

    You can modify the function with
    return ' &hellip; <a href="'. get_permalink() . '" rel="nofollow">Continue reading &rarr;</a>';

  14. Tompa

    First of all: Thanks for this piece of code, and speciall thanks to Paul who wrote a piece that was better suited for my purpose! However, it woulden´t work in WP 3 because of the change to GUID in WP 2.5. ( http://codex.wordpress.org/Function_Reference/get_post )

    So I changed it a little bit;

    function my_excerpt($excerpt = '', $excerpt_length = 50, $readmore = "Read more »", $tags = '<a>') {
    global $post;
    $string_check = explode(' ', $excerpt);

    if (count($string_check, COUNT_RECURSIVE) &gt; $excerpt_length) {
    $new_excerpt_words = explode(' ', $excerpt, $excerpt_length+1);
    array_pop($new_excerpt_words);
    $excerpt_text = implode(' ', $new_excerpt_words);
    $temp_content = strip_tags($excerpt_text, $tags);
    $short_content = preg_replace('`\[[^\]]*\]`','',$temp_content);
    $short_content .= ' ... <a href="' . get_permalink() . '" rel="nofollow">post_title . '"&gt;' . $readmore . '</a>';
    return $short_content;
    } else {
    return $excerpt;
    }
    }

    Works for me, hope it will for you to! :)

    Oh, added support for shorter posts as well.

  15. Peter Ahrens

    Thanks for that, it's exactly what I needed. My homepage recent posts have only 15 words, my blog uses full posts and the archive uses 50 words. I thought it was going to be hard to do that, proves not the be the case at all.

  16. Paul

    @ Tompa and Paul

    Many thanks ... works prefectly ... except for a couple of little errors in Tompa's code... (one due to the pasting of code) ... not sure how to paste in code here myself tho.... but here goes.....


    function my_excerpt($excerpt = '', $excerpt_length = 50, $readmore = "Read more »", $tags = '') {
    global $post;
    $string_check = explode(' ', $excerpt);

    if (count($string_check, COUNT_RECURSIVE) > $excerpt_length) {
    $new_excerpt_words = explode(' ', $excerpt, $excerpt_length+1);
    array_pop($new_excerpt_words);
    $excerpt_text = implode(' ', $new_excerpt_words);
    $temp_content = strip_tags($excerpt_text, $tags);
    $short_content = preg_replace('`\[[^\]]*\]`','',$temp_content);
    $short_content .= ' ... ' .post_title . '"»' . $readmore . '';
    return $short_content;
    } else {
    return $excerpt;
    }
    }

    then in your template

  17. Paul

    Hhhmmm .... kinda ....

    you'll need to replace the special character for "read more" with &-r-a-q-u-o; (delete all dashes) and make sure the "greater than" after COUNT_RECURSIVE is correct....

    Anyway... MIchael .... Many thanks for the post....

    Any chance you could put an indicator beside the comments box for hoe yo paste code.... :-)

    :-p

  18. Paul

    Apologies for the multiple comments .... just spotted another bit worth tweaking ....

    This final code works perfectly in WP 3.1.1 .... Thanks again to all here who know waaay more than I do!!!


    function my_excerpt($excerpt = '', $excerpt_length = 50, $readmore = "Read more »", $tags = '') {
    global $post;
    $string_check = explode(' ', $excerpt);
    if (count($string_check, COUNT_RECURSIVE) > $excerpt_length) {
    $new_excerpt_words = explode(' ', $excerpt, $excerpt_length+1);
    array_pop($new_excerpt_words);
    $excerpt_text = implode(' ', $new_excerpt_words);
    $temp_content = strip_tags($excerpt_text, $tags);
    $short_content = preg_replace('`\[[^\]]*\]`','',$temp_content);
    $short_content .= ' ...
    '. $readmore . '';
    return $short_content;
    } else {
    return $excerpt;
    }
    }

  19. Imad

    Great piece of code, i noticed lots of changes with time passing and wp versions, if someone could make a plugin from that it would be better for updates and maintenance than updating the code each time, i mean for simple wp users like me, but anyway i got what i needed why am i asking for more...Big Thanks

2 pingbacks

  1. Verschiedene excerpt Längen mit WordPress 2.9 - WordPress 2.9, Filter, the_excerpt, apply_fliters - dynamicinternet
  2. WPEngineer gears up for their own WordPress Advent Calendar | WPCandy