Working with excerpts in WordPress, or why isn’t this filter working?

When is an excerpt not an excerpt?

If you call get_the_excerpt() WordPress returns a string that looks like an excerpt – but it might not be. If your post doesn’t have a handcrafted excerpt, WordPress returns an automatically generated word-counted trimmed-down version of the full post content (see codex).

TL/DR: WordPress returns a string for get_the_excerpt() even when has_excerpt() is FALSE.

I’d used this bit of code to automatically add a ‘read more’ link at the end of every excerpt on a search page.

function ds_excerpt_read_more( $output ) {
 
	$read_more_link = ' (<a class="more-link" href="' . get_permalink() . '">Read more</a>)';
 
	if ( has_excerpt() && ! is_attachment() & is_search() ) {
 
		$output .= " " . $read_more_link;
 
	}
	return $output;
}
add_filter( 'get_the_excerpt', 'ds_excerpt_read_more'  );

Problem was, it wasn’t working everywhere – some posts didn’t have the modified excerpt.

has_excerpt() was the problem – it only returns TRUE if there is a manual excerpt.

So this works better:

function ds_excerpt_read_more( $output ) {
 
	$read_more_link = ' (<a class="more-link" href="' . get_permalink() . '">Read more</a>)';
 
	if ( has_excerpt() && ! is_attachment() & is_search() ) {
 
		$output .= " " . $read_more_link;
 
	} elseif (is_search() &&  ! has_excerpt() )  {
 
		$excerpt_length = apply_filters('excerpt_length', 55);
		$output = wp_trim_words( $output, $excerpt_length, '' );
		$output .= " " . $read_more_link;
 
	}
	return $output;
}
add_filter( 'get_the_excerpt', 'ds_excerpt_read_more'  );

but this is best:

function ds_excerpt_read_more( $output ) {
 
	if (  is_search() && ! is_attachment() ) {
 
		$read_more_link = ' (<a class="more-link" href="' . get_permalink() . '">Read more</a>)';
 
		if ( ! has_excerpt() ) {
 
			$excerpt_length = apply_filters('excerpt_length', 55);
			$output = wp_trim_words( $output, $excerpt_length, '' );
 
			/* Finds the last full stop in the excerpt, removes everything after it. */
			if ( ( $pos = mb_strrpos( $output, '.' ) ) !== false ) {
				$output = substr( $output, 0, $pos + 2 );
			}
		}
 
		/* Appends a 'read more' link at the end of the excerpt - if it's a search */
		$output .= " " . $read_more_link;
 
	}
	return $output;
}
add_filter( 'get_the_excerpt', 'ds_excerpt_read_more'  );

How to add a new Page Template to WordPress

You have to do two things to add a new page template to WordPress.

1. Add a file with the correct name

WordPress uses a template hierarchy – you need to give your template the right name. Either page-ID.php – where ID is the post ID of the page you are targeting, or page-SLUG.php – where SLUG is either the slug of the page you are targeting or an understandable name you can assign through the page interface to pages.

2. Add a ‘Template Name’ declaration at the start of your template file

For WordPress to pick your template up, you need to start each page template file with a Template Name string followed by a unique name for the template:

/*
Template Name: Offer page template
*/