get_the_excerpt │ filter-hook │ WP 1.2.0

Allows changing the post excerpt retrieved through get_the_excerpt().

The filter is applied to the post_excerpt field value before the result is returned. Changes are not saved to the database. It also affects the_excerpt(), which gets the text through get_the_excerpt().

By default, wp_trim_excerpt() is attached to the hook at priority 10. If the passed text is empty (after trimming whitespace), it creates an excerpt from the post content. This is usually the first 55 words without HTML, ending with […]. The excerpt_length and excerpt_more filters change the length and ending. A non-empty manually specified excerpt is not trimmed automatically.

Choose the callback priority according to the task:

  • Less than 10: change the original text before an excerpt is generated automatically. If a non-empty string is returned, the default generation from the content will not run.
  • Greater than 10: change the result after the default processing.

The hook is also used in the REST API when preparing excerpt.rendered for posts and caption.rendered for attachments. The raw fields contain the original value. If a change is needed only for a specific post type, check $post->post_type.

In get_the_excerpt() itself, the hook is not called if the post is not found or post_password_required() returns true.

In the REST API, it is called before the password check for excerpt.rendered; if access is denied, this field is then set to an empty string.

Use the the_excerpt filter to change formatting when outputting through the_excerpt(). It is applied after get_the_excerpt; among other things, typography and paragraph insertion are attached to it.

Usage

add_filter( 'get_the_excerpt', 'wp_kama_get_the_excerpt_filter', 10, 2 );

/**
 * Function for `get_the_excerpt` filter-hook.
 * 
 * @param string  $post_excerpt The post excerpt.
 * @param WP_Post $post         Post object.
 *
 * @return string
 */
function wp_kama_get_the_excerpt_filter( $post_excerpt, $post ){
	// filter...
	return $post_excerpt;
}
$post_excerpt(string)
Excerpt being filtered.
Initially, this is the $post->post_excerpt value, which may be empty.
By the time the callback is called, previous filters, including wp_trim_excerpt(), may have already changed the text.
$post(WP_Post)
Object for the post whose excerpt is being retrieved.
Use this object instead of the global $post: the excerpt may be retrieved for another post.

Examples

#1 Add a "Read more" link to the excerpt

This example applies only to post posts with a filled excerpt field. The has_excerpt() check distinguishes a manual excerpt from an automatically generated one.

add_filter( 'get_the_excerpt', 'mytheme_excerpt_read_more', 20, 2 );

function mytheme_excerpt_read_more( $excerpt, $post ) {

	if ( 'post' !== $post->post_type || ! has_excerpt( $post ) ) {
		return $excerpt;
	}

	return $excerpt . sprintf( <a href="%s">%s</a>',
		esc_url( get_permalink( $post ) ),
		esc_html__( 'Read more', 'mytheme' )
	);
}

#2 Limit the excerpt length

The excerpt_length filter by itself does not trim an excerpt. Here, explicitly apply the length and ending through wp_trim_words(). This also removes HTML tags.

add_filter( 'get_the_excerpt', 'mytheme_trim_manual_excerpt', 20, 2 );

function mytheme_trim_manual_excerpt( $excerpt, $post ) {

	if ( 'post' !== $post->post_type || ! has_excerpt( $post ) ) {
		return $excerpt;
	}

	$length = (int) apply_filters( 'excerpt_length', (int) _x( '55', 'excerpt_length' ) );
	$more   = apply_filters( 'excerpt_more', ' […]' );

	return wp_trim_words( $excerpt, $length, $more );
}

The same rule applies to any non-empty string: passing it to

apply_filters( 'get_the_excerpt', $text, $post )

does not start the default trimming. Call wp_trim_words() first. When calling the filter manually, pass a valid post object as its second argument because callbacks may expect it.

#3 Replace an empty result with placeholder text

Priority 20 allows the default generation to run first. The placeholder appears only if the result is still empty. Use priority 5 if you need a placeholder instead of generation from the content.

add_filter( 'get_the_excerpt', 'mytheme_excerpt_fallback', 20, 2 );

function mytheme_excerpt_fallback( $excerpt, $post ) {

	if ( 'post' === $post->post_type && '' === trim( $excerpt ) ) {
		return __( 'Open the post to read the article.', 'mytheme' );
	}

	return $excerpt;
}

Changelog

Since 1.2.0 Introduced.
Since 4.5.0 Introduced the $post parameter.

Where the hook is called

get_the_excerpt()
get_the_excerpt
WP_REST_Posts_Controller::prepare_item_for_response()
get_the_excerpt
WP_REST_Attachments_Controller::prepare_item_for_response()
get_the_excerpt
wp-includes/post-template.php 436
return apply_filters( 'get_the_excerpt', $post->post_excerpt, $post );
wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php 2031
$excerpt = apply_filters( 'get_the_excerpt', $post->post_excerpt, $post );
wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php 1444
$caption = apply_filters( 'get_the_excerpt', $post->post_excerpt, $post );

Where the hook is used in WordPress

wp-includes/default-filters.php 219
add_filter( 'get_the_excerpt', 'wp_trim_excerpt', 10, 2 );