I feel like I must be missing something pretty obvious, here, but I can’t seem to get WordPress to cooperate.
I’m generating Facebook OG tags with a function. Everything works fine, except for the excerpt.
Since the deprecation of get_the_excerpt($post->ID)
, is there another way to create an excerpt without having to create a whole new loop? It seems excessive to me.
My first instinct was to use apply_filters()
:
$description = apply_filters('the_excerpt', get_post($post->ID)->post_content);
That gives me the full post, complete with HTML-formatted content. Okay, must be wrong. So I tried the next logical idea:
$description = apply_filters('get_the_excerpt', get_post($post->ID)->post_content);
No dice. Now there’s no HTML, but it’s still the full post (which is really confusing).
Okay, no problem. Let’s skip all the fancy stuff and just go for the trimmed entry:
$description = wp_trim_excerpt(get_post($post->ID)->post_content);
No change.
So, my question is this: what the heck is going on? Is there something I’m missing, here?
I got into the WP core to find how the_excerpt()
works, and it appears to be identical to my call:
/**
* Display the post excerpt.
*
* @since 0.71
* @uses apply_filters() Calls 'the_excerpt' hook on post excerpt.
*/
function the_excerpt() {
echo apply_filters('the_excerpt', get_the_excerpt());
}
I have a few questions based on my findings:
- Why isn’t the filter applying as expected?
- Is there a way to get the excerpt outside of the loop without creating a new loop?
- Am I crazy?
Thanks in advance for having a look. I’m fairly stumped, here.
3 s
Turns out the answer was in wp_trim_excerpt()
.
It’s defined in wp-includes/functions.php:1879
:
/**
* Generates an excerpt from the content, if needed.
*
* The excerpt word amount will be 55 words and if the amount is greater than
* that, then the string ' [...]' will be appended to the excerpt. If the string
* is less than 55 words, then the content will be returned as is.
*
* The 55 word limit can be modified by plugins/themes using the excerpt_length filter
* The ' [...]' string can be modified by plugins/themes using the excerpt_more filter
*
* @since 1.5.0
*
* @param string $text Optional. The excerpt. If set to empty, an excerpt is generated.
* @return string The excerpt.
*/
function wp_trim_excerpt($text="") {
$raw_excerpt = $text;
if ( '' == $text ) {
$text = get_the_content('');
$text = strip_shortcodes( $text );
$text = apply_filters('the_content', $text);
$text = str_replace(']]>', ']]>', $text);
$excerpt_length = apply_filters('excerpt_length', 55);
$excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
$text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
}
return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
}
So any text passed in doesn’t get processed; it only works if it’s called with an empty parameter.
To solve this, I added a quick filter to my theme that solves the problem:
/**
* Allows for excerpt generation outside the loop.
*
* @param string $text The text to be trimmed
* @return string The trimmed text
*/
function rw_trim_excerpt( $text="" )
{
$text = strip_shortcodes( $text );
$text = apply_filters('the_content', $text);
$text = str_replace(']]>', ']]>', $text);
$excerpt_length = apply_filters('excerpt_length', 55);
$excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
return wp_trim_words( $text, $excerpt_length, $excerpt_more );
}
add_filter('wp_trim_excerpt', 'rw_trim_excerpt');
It’s somewhat redundant, but I like it better than opening new loops every time I want to generate an excerpt.