67

As it says in the title, I'm looking for multiple excerpt lengths in WordPress.

I understand you can do this in functions.php:

function twentyten_excerpt_length( $length ) {
    return 15;
}
add_filter( 'excerpt_length', 'twentyten_excerpt_length' );

What I want to know is how you can have multiple of these each returning different numerical values so I can get short excerpts for sidebar loops, longer excerpts for featured loops, and the longest excerpt for the main article.

Something like using these in the templates:

<?php the_excerpt('length-short') ?>
<?php the_excerpt('length-medium') ?>
<?php the_excerpt('length-long') ?>

Cheers, Dave

davebowker
  • 4,475
  • 7
  • 27
  • 32

13 Answers13

103

How about...

function excerpt($limit) {
      $excerpt = explode(' ', get_the_excerpt(), $limit);

      if (count($excerpt) >= $limit) {
          array_pop($excerpt);
          $excerpt = implode(" ", $excerpt) . '...';
      } else {
          $excerpt = implode(" ", $excerpt);
      }

      $excerpt = preg_replace('`\[[^\]]*\]`', '', $excerpt);

      return $excerpt;
}

function content($limit) {
    $content = explode(' ', get_the_content(), $limit);

    if (count($content) >= $limit) {
        array_pop($content);
        $content = implode(" ", $content) . '...';
    } else {
        $content = implode(" ", $content);
    }

    $content = preg_replace('/\[.+\]/','', $content);
    $content = apply_filters('the_content', $content); 
    $content = str_replace(']]>', ']]&gt;', $content);

    return $content;
}

then in your template code you just use..

<?php echo excerpt(25); ?>

from: http://bavotasan.com/tutorials/limiting-the-number-of-words-in-your-excerpt-or-content-in-wordpress/

JohnHoulderUK
  • 639
  • 2
  • 8
  • 27
Marty
  • 4,619
  • 2
  • 24
  • 35
80

As for now, you can upgrade Marty's reply:

function excerpt($limit) {
    return wp_trim_words(get_the_excerpt(), $limit);
}

You can also define custom 'read more' link this way:

function custom_read_more() {
    return '... <a class="read-more" href="'.get_permalink(get_the_ID()).'">more&nbsp;&raquo;</a>';
}
function excerpt($limit) {
    return wp_trim_words(get_the_excerpt(), $limit, custom_read_more());
}
Michał Rybak
  • 8,648
  • 3
  • 42
  • 54
  • 4
    By far the best and simplest response. Excellent use of a built-in WP function. Thank you for not over-engineering a solution. – Ryan Burney Feb 18 '14 at 18:23
  • 1
    @Michal, great piece of code, never thought that it could actually be so easy – Pieter Goosen Feb 20 '14 at 16:41
  • 2
    Sweet - this is the way to go. And in response to Tri Nguyen's concerns about data sanitization: `wp_trim_words()` calls `wp_strip_all_tags()` on the text, so no worries about breaking HTML in the post content. – Dan J Apr 03 '14 at 03:12
  • Excellent approach, just set the maximum excerpt length you want to use int the `excerpt_length` filter and use `wp_trim_words` everywhere else. – Javier Villanueva Apr 20 '15 at 22:05
  • 6
    It's probably worth noting that if you want a `$limit` to be more than 55 words, you'll have to adjust the default excerpt length too. `function custom_excerpt_length( $length ) { return 135; } add_filter( 'excerpt_length', 'custom_excerpt_length', 999 );` – evu Jun 17 '15 at 10:42
  • 7
    It's times like this that I think Stackoverflow needs an 'archive answer and pick new one' type feature. Things change yo. – Nathan Hornby Jul 02 '15 at 15:14
  • This doesn't quite work if the text creating the excerpt is less than the `$limit`. The "Continue reading →" text from `get_the_excerpt()` appears on the end of the excerpt as plain text. I prefer @Olaf s solution below. – Slab Mar 29 '17 at 13:52
  • Simple and efficient, i was able to make it loop friendly which is awesome – Kolawole Emmanuel Izzy Jul 10 '19 at 07:35
26

This is what I came up with.

Add this to your functions.php

class Excerpt {

  // Default length (by WordPress)
  public static $length = 55;

  // So you can call: my_excerpt('short');
  public static $types = array(
      'short' => 25,
      'regular' => 55,
      'long' => 100
    );

  /**
   * Sets the length for the excerpt,
   * then it adds the WP filter
   * And automatically calls the_excerpt();
   *
   * @param string $new_length 
   * @return void
   * @author Baylor Rae'
   */
  public static function length($new_length = 55) {
    Excerpt::$length = $new_length;

    add_filter('excerpt_length', 'Excerpt::new_length');

    Excerpt::output();
  }

  // Tells WP the new length
  public static function new_length() {
    if( isset(Excerpt::$types[Excerpt::$length]) )
      return Excerpt::$types[Excerpt::$length];
    else
      return Excerpt::$length;
  }

  // Echoes out the excerpt
  public static function output() {
    the_excerpt();
  }

}

// An alias to the class
function my_excerpt($length = 55) {
  Excerpt::length($length);
}

It can be used like this.

my_excerpt('short'); // calls the defined short excerpt length

my_excerpt(40); // 40 chars

This is the easiest way that I know of to add filters, that are callable from one function.

Baylor Rae'
  • 3,995
  • 20
  • 39
  • I preferred this answer as it's a nice way to come up with code. Thanks Baylor. – Mayeenul Islam Oct 26 '13 at 16:35
  • 2
    nice solution but it took me a while to get it working as it lacks the priority to be effective in current (2013) versions of Wordpress: use `add_filter('excerpt_length', 'Excerpt::new_length', 999);` instead (notice the last parameter) – Guerilla Jan 03 '14 at 14:21
10

I was looking for this feature as well and most of the functions here are good and flexible. For my own case I was looking for a solution that shows a different excerpt length only on specific pages. I'm using this:

function custom_excerpt_length( $length ) {
    return (is_front_page()) ? 15 : 25;
}
add_filter( 'excerpt_length', 'custom_excerpt_length', 999 );

Paste this code inside the themes functions.php file.

Olaf
  • 131
  • 1
  • 2
6

You can add to your functions.php file this function

function custom_length_excerpt($word_count_limit) {
    $content = wp_strip_all_tags(get_the_content() , true );
    echo wp_trim_words($content, $word_count_limit);
}

Then call it in your template like this

<p><?php custom_length_excerpt(50); ?>

The wp_strip_all_tags should prevent stray html tags from breaking the page.


Documentation on functions

Mike Grace
  • 16,636
  • 8
  • 59
  • 79
  • 3
    is there a way can we skip html code using example above? shortcode is visible in some of my pages – Marko Jul 20 '14 at 08:51
5

Going back to Marty's reply:

I know it's been well over a year since this reply got published, but it's better late than never. For this to work with limits of over the WordPress default of 55, you need to replace this line:

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

with this line:

     $excerpt = explode(' ', get_the_content(), $limit);

Otherwise, the function only works with an already trimmed-down piece of text.

0x61696f
  • 173
  • 3
  • 9
4

I think we can now use wp_trim_words see here. Not sure what extra data escaping and sanitization needed to use this function, but it looks interesting.

Tri Nguyen
  • 9,950
  • 8
  • 40
  • 72
3

Here an easy way to limit the content or the excerpt

$content = get_the_excerpt();
$content = strip_tags($content);    
echo substr($content, 0, 255);

change get_the_excerpt() by get_the_content() if you want the contents.

Regards

Mohammed
  • 390
  • 3
  • 7
2

I would do like this :

function _get_excerpt($limit = 100) {
    return has_excerpt() ? get_the_excerpt() : wp_trim_words(strip_shortcodes(get_the_content()),$limit);
}

Usage :

echo _get_excerpt(30); // Inside the loop / query

Why ?

  • If has_excerpt should return given excerpt
  • It not, So trim words / strip shortcodes from the_content
l2aelba
  • 21,591
  • 22
  • 102
  • 138
  • isn't this what the get_the_excerpt func does automatically? your function doesnt really trim existing excerpt... – Sagive Aug 04 '19 at 07:11
0

I thing it is possible to create a short code , i did not try it but i wrote for you the main idea about its structure

function twentyten_excerpt_length($atts,$length=null){
    shortcode_atts(array('exlength'=>'short'),$atts);

    if(!isset($atts['exlength']) || $atts['exlength'] == 'short') {
        return 15;
    }elseif( $atts['exlength'] == 'medium' ){
        return 30;  // or any value you like
    }elseif( $atts['exlength'] == 'long' ){
        return 45;  // or any value you like
    }else{
        // return nothing
    }
}

add_shortcode('the_excerpt_sc','twentyten_excerpt_length');

so you can use it like so

[the_excerpt_sc exlength="medium"]
usama sulaiman
  • 2,013
  • 4
  • 24
  • 37
0

I know this is a really old thread, but I just struggled with this problem and none of the solutions I found online worked properly for me. For one thing my own "excerpt_more"-filter was always cut off.

The way I solved it is ugly as hell, but it's the only working solution I could find. The ugliness involves modifying 4 lines of WP core(!!) + the use of yet another global variable (although WP already does this so much I don't feel too bad).

I changed wp_trim_excerpt in wp-includes/formatting.php to this:

<?php
function wp_trim_excerpt($text = '') {
    global $excerpt_length;
    $len = $excerpt_length > 0 ? $excerpt_length : 55;
    $raw_excerpt = $text;
    if ( '' == $text ) {
        $text = get_the_content('');

        $text = strip_shortcodes( $text );

        $text = apply_filters('the_content', $text);
        $text = str_replace(']]>', ']]&gt;', $text);
        $excerpt_length = apply_filters('excerpt_length', $len);
        $excerpt_more = apply_filters('excerpt_more', ' ' . '[&hellip;]');
        $text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
    }
    $excerpt_length = null;
    return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
}

The only new stuff is the $excerpt_length and $len bits.

Now if I want to change the default length I do this in my template:

<?php $excerpt_length = 10; the_excerpt() ?>

Changing core is a horrible solution so I'd love to know if someone comes up with something better.

powerbuoy
  • 12,460
  • 7
  • 48
  • 78
  • Hmm... how come [Michal's solution](http://stackoverflow.com/a/17177847/238688) (use `wp_trim_words()`) doesn't work for you? Much nicer than hacking core... – Dan J Apr 03 '14 at 03:11
  • Hmm.. must've missed it when I wrote this. Definitely gonna try it out on my current WP projects. I _have_ had problems with WP before though when using get_the_* functions instead of the_* functions where they don't return the exact same thing (`the_content()` and `get_the_content()` in my experience) – powerbuoy Apr 03 '14 at 18:04
0

Be careful using some of these methods. Not all of them strip the html tags out, meaning if someone inserts a link to a video (or url) in the first sentence of their post, the video (or link) will show up in the excerpt, possibly blowing up your page.

-1

I wrote an article about using custom excerpt length in WordPress. There area a number of ways to limit & control post excerpt length.

  1. Limit post excerpt length or post content length using number of words.
  2. Limiting excerpt length to a number of characters.
  3. Limit post summary by adding ‘read more’ tag.
  4. Enabling custom excerpt to write your own summary for each post.
  5. Control Excerpt Length using Filters

I hope this will help you a lot.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
poonam
  • 1
  • 1