Replacing WordPress content with an excerpt without editing theme files

I’ve been working away at a new theme for the past couple of weeks. Actually, it’s a theme framework that I’ve been building upon for the last two months or so, slowly trying to put all the bits and pieces together.

I ran into a bit of a hitch though.

Let’s suppose our front page and archives used the WordPress function <?php the_content(); ?> to retrieve all post content. Let’s further suppose we’re want to modify this with a child theme to show excerpts instead of the entire post.

Yes, we could easily just change <?php the_content(); ?> to <?php the_excerpt(); ?>. But, I don’t want to edit the core files at all. I want to be able to upgrade my theme without my modifications being broken.

Solution

WordPress filters.

In my child theme’s functions.php file, I added this bit of PHP:

// Add filter to the_content
	add_filter('the_content', 'my_excerpts');

This tells WP that we want to filter the_content() with our own function.

Here’s what that function looks like:

function my_excerpts($content = false) {

// If is the home page, an archive, or search results
	if(is_front_page() || is_archive() || is_search()) :
		global $post;
		$content = $post->post_excerpt;

	// If an excerpt is set in the Optional Excerpt box
		if($content) :
			$content = apply_filters('the_excerpt', $content);

	// If no excerpt is set
		else :
			$content = $post->post_content;
			$excerpt_length = 55;
			$words = explode(' ', $content, $excerpt_length + 1);
			if(count($words) > $excerpt_length) :
				array_pop($words);
				array_push($words, '...');
				$content = implode(' ', $words);
			endif;
			$content = '<p>' . $content . '</p>';

		endif;
	endif;

// Make sure to return the content
	return $content;

}

Now, we’ve changed the instances of the_content() that we want to excerpts. This example doesn’t strip the tags of the excerpt like the default WordPress function, but we can easily change that by changing this line:

$content = $post->post_content;

to:

$content = $post->post_content;
$content = strip_shortcodes($content);
$content = str_replace(']]>', ']]&gt;', $content);
$content = strip_tags($content);

There may be a better way to filter the_content(), and I’d love to see what you can come up with if so.