Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm building a theme that is going to show excerpts on the homepage for potentially dozens of posts. I don't have manual excerpts on all of my posts, so $post->post_excerpt is empty for many posts. In the event that there isn't a manual excerpt, I would like to use the built-in get_the_excerpt() function, but it isn't available outside the loop.

Tracking down the function, it looks like it uses wp_trim_excerpt from wp-includes/formatting.php to create excerpts on the fly. I am calling it in my code like wp_trim_excerpt( $item->post_content ), but it is simply returning the full content. Am I doing something wrong?

I know that I can create my own function to create an excerpt, but I like to use built-in functions where possible, keeping my code compatible with other potential plugins / filters.

http://adambrown.info/p/wp_hooks/hook/wp_trim_excerpt?version=3.0&file=wp-includes/formatting.php

share|improve this question
    
You could try calling the excerpt filters... $myvar = apply_filters( 'the_excerpt', $myvar ); –  t31os Jan 15 '11 at 16:14

6 Answers 6

up vote 8 down vote accepted

wp_trim_excerpt() has a little curious mechanics - if anything is passed to it then it does nothing.

Here is basic logic behind it:

  • get_the_excerpt() checks for manual excerpt;
  • wp_trim_excerpt() chimes in if there is no manual excerpt and makes one from content or teaser.

Both are tightly tied to global variables and so Loop.

Outside the Loop you are better of taking code out of wp_trim_excerpt() and writing your own trim function.

share|improve this answer

+1 to Rast. It is very weird that there is no such thing as get_the_excerpt($post->ID), when it should be quite obvious that it should. Anyway, here is wp_trim_excerpt() in wordpress version 3.0.4:

http://core.trac.wordpress.org/browser/tags/3.0.4/wp-includes/formatting.php

function wp_trim_excerpt($text) {
1824            $raw_excerpt = $text;
1825            if ( '' == $text ) {
1826                    $text = get_the_content('');
1827    
1828                    $text = strip_shortcodes( $text );
1829    
1830                    $text = apply_filters('the_content', $text);
1831                    $text = str_replace(']]>', ']]>', $text);
1832                    $text = strip_tags($text);
1833                    $excerpt_length = apply_filters('excerpt_length', 55);
1834                    $excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
1835                    $words = preg_split("/[\n\r\t ]+/", $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
1836                    if ( count($words) > $excerpt_length ) {
1837                            array_pop($words);
1838                            $text = implode(' ', $words);
1839                            $text = $text . $excerpt_more;
1840                    } else {
1841                            $text = implode(' ', $words);
1842                    }
1843            }
1844            return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
1845    }

You can see on line 1826 that it is linked to the $post global variable via get_the_contents. And yes, I have no idea what were they thinking. But from here, replace the get_the_content with $text in your own my_excerpt, and it should behave in a similar fashion.

share|improve this answer
    
azure_ardee: consider using wp_trim_words() –  user24378 Dec 3 '12 at 18:35

Update:

Here is a derivative of wp_trim_excerpt() which I used. Works perfectly. Derived from Wordpress version 3.0.4

function my_excerpt($text, $excerpt)
{
    if ($excerpt) return $excerpt;

    $text = strip_shortcodes( $text );

    $text = apply_filters('the_content', $text);
    $text = str_replace(']]>', ']]>', $text);
    $text = strip_tags($text);
    $excerpt_length = apply_filters('excerpt_length', 55);
    $excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
    $words = preg_split("/[\n\r\t ]+/", $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
    if ( count($words) > $excerpt_length ) {
            array_pop($words);
            $text = implode(' ', $words);
            $text = $text . $excerpt_more;
    } else {
            $text = implode(' ', $words);
    }

    return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
}
share|improve this answer
    
You don't have to post a new answer, you can always edit your old one to include new information. You could, for example, copy the link to the WP code from your first answer into this one and then delete your first answer. –  Jan Fabry Jan 25 '11 at 9:01

The get_the_content() function would return full content if $more != 0. You have to set global variable $more to 0 to make sure get_the_content() function return excerpt.

Modified wp_trim_excerpt() function:

function wp_trim_excerpt($text) {
    $raw_excerpt = $text;
    if ( '' == $text ) {
        global $more;
        $tmp = $more;
        $more = 0;
        $text = get_the_content('');
        $more = $tmp;

        $text = strip_shortcodes( $text );

        $text = apply_filters('the_content', $text);
        $text = str_replace(']]>', ']]>', $text);
        $text = strip_tags($text);
        $excerpt_length = apply_filters('excerpt_length', 55);
        $excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
        $words = preg_split("/[\n\r\t ]+/", $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
        if ( count($words) > $excerpt_length ) {
            array_pop($words);
            $text = implode(' ', $words);
            $text = $text . $excerpt_more;
        } else {
            $text = implode(' ', $words);
        }
    }
    return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
}
share|improve this answer

Here's my take on a "trim_excerpt" that takes the post object or a post ID as a parameter.

Obviously based on what's in core. Don't know why this (and get_the_author()) don't have non-loop equivalents.

/**
     * Generates an excerpt from the content, if needed.
     *
     * @param int|object $post_or_id can be the post ID, or the actual $post object itself
     * @param string $excerpt_more the text that is applied to the end of the excerpt if we algorithically snip it
     * @return string the snipped excerpt or the manual excerpt if it exists         
     */
    function zg_trim_excerpt($post_or_id, $excerpt_more = ' [...]') {
        if ( is_object( $post_or_id ) ) $postObj = $post_or_id;
        else $postObj = get_post($post_or_id);

        $raw_excerpt = $text = $postObj->post_excerpt;
        if ( '' == $text ) {
            $text = $postObj->post_content;

            $text = strip_shortcodes( $text );

            $text = apply_filters('the_content', $text);
            $text = str_replace(']]>', ']]>', $text);
            $text = strip_tags($text);
            $excerpt_length = apply_filters('excerpt_length', 55);

            // don't automatically assume we will be using the global "read more" link provided by the theme
            // $excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
            $words = preg_split("/[\n\r\t ]+/", $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
            if ( count($words) > $excerpt_length ) {
                array_pop($words);
                $text = implode(' ', $words);
                $text = $text . $excerpt_more;
            } else {
                $text = implode(' ', $words);
            }
        }
        return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
    }
share|improve this answer

Since WP 3.3.0, wp_trim_words() is helpful if you're able to get the content that you want to generate an excerpt for. Hope that's helpful to someone and it saves creating your own word counting function.

http://codex.wordpress.org/Function_Reference/wp_trim_words

share|improve this answer
2  
This should now be the accepted answer. No need to write your own trim functions... –  ZweiBlumen Mar 26 '12 at 7:25

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.