I often wonder why there isn’t a function in WordPress core that will get a post excerpt outside of the loop. Here is a function that will do just that:
<?php | |
// Make sure to prefix the function if you do not use a namespace. | |
// namespace TimJensen\HelperFunctions; | |
/** | |
* Returns an auto generated post excerpt, or a manual excerpt if one has been set. | |
* | |
* @version 1.2.1 | |
* | |
* @param int $post_id Required. Post ID. | |
* @param mixed $excerpt_length Optional. Length of the automatic except. | |
* Does not affect the manual excerpt length. Defaults to 55. | |
* @param mixed $excerpt_more Optional. Text that appends the excerpt. Defaults to '...'. | |
* @param bool $more_link Optional. Includes a link to the singular post. Defaults to true. | |
* | |
* @return string | |
*/ | |
function get_post_excerpt( $post_id, $excerpt_length = null, $excerpt_more = null, $more_link = true ) { | |
$post = get_post( $post_id ); | |
if ( null === $excerpt_length ) { | |
$excerpt_length = apply_filters( 'excerpt_length', 55 ); | |
} | |
if ( $post->post_excerpt ) { | |
$excerpt = $post->post_excerpt; | |
} else { | |
$excerpt = strip_shortcodes( $post->post_content ); | |
$excerpt = apply_filters( 'the_content', $excerpt ); | |
$excerpt = str_replace( ']]>', ']]>', $excerpt ); | |
$original_word_count = str_word_count( strip_tags( $excerpt ) ); | |
$excerpt = wp_trim_words( $excerpt, $excerpt_length, '' ); | |
$is_trimmed_excerpt = str_word_count( $excerpt ) < $original_word_count; | |
} | |
if ( null === $excerpt_more ) { | |
$excerpt_more = apply_filters( 'excerpt_more', '…' ); | |
} | |
// Remove the excerpt more (i.e., '...') when there is no more text to show. | |
$excerpt_more = empty( $is_trimmed_excerpt ) ? '' : $excerpt_more; | |
$excerpt = apply_filters( 'get_post_excerpt_excerpt', $excerpt . $excerpt_more ); | |
if ( false === $more_link ) { | |
return $excerpt; | |
} else { | |
$more_link = sprintf( '<a href="%s" class="more-link read-more-link">%s</a>', | |
get_the_permalink( $post->ID ), | |
apply_filters( 'get_post_excerpt_read_more_text', 'Read More' ) | |
); | |
} | |
return $excerpt . apply_filters( 'get_post_excerpt_read_more_link', $more_link ); | |
} |
You call the function by simply passing in the ID of the post whose excerpt you want to retrieve, like this:$excerpt = get_post_excerpt( 21 );
To override the default excerpt length of 55 words, you can pass a second parameter:$excerpt = get_post_excerpt( 21, 85 );
To change the excerpt more string from the default ellipsis (…), you can pass a third parameter:$excerpt = get_post_excerpt( 21, 85, '----' );
By default the excerpt will also contain a link to the singular post. This can be disabled by passing a fourth parameter:$excerpt = get_post_excerpt( 21, 85, '----', false );
Additionally there are three useful filters that can be used like this:add_filter( 'get_post_excerpt_excerpt', 'callback_function_to_modify_the_post_excerpt' );
add_filter( 'get_post_excerpt_read_more_text', 'callback_function_to_modify_the_read_more_text' );
add_filter( 'get_post_excerpt_read_more_link', 'callback_function_to_modify_the_read_more_link' );
Evin says
Thank you so much for this! I spent about 6 hours yesterday trying to pull an excerpt using a post ID outside the loop, nothing would work! This did. Thanks a lot!
Tim Jensen says
You’re welcome, Evin! I’m glad you found it to be helpful.