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(']]>', ']]>', $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.