More Tags or Excerpts

Explanation of Excerpts

There’s two ways main ways to display posts on the home page and archive pages in WordPress. The first is to use the_excerpt tag, which checks to see if an excerpt has been manually entered. If it has, WordPress will display it. If it hasn’t, it’ll take the first 55 words from the post and display that instead.

Using the_excerpt is a perfect way to display a tiny snippet of the post so people can easily scroll through all the topics. When using the_excerpt, WordPress will also automatically remove any images or html tags that might mess with the layout in a shortened version.

Explanation of the_content with More Tags

The other way to display posts is to use the_content (which is how the theme 2010 works). In this case, WordPress will display the full content of the post unless someone has manually entered a “!– more –” tag. This is a great to occasionally to show the full content, and other times just a teaser.

The problem with using the_content and more tags is that you may have a large image or a movie above the more tag that you want to show on the full post, but not in it’s excerpt form.

I haven’t yet found the perfect way to do this, but I’ve gotten close. Justin Tadlock also has a similar article about this which covers content and excerpt filters in more depth.

Display the_content up to the More Tag Without Images or Objects

If you want to display the_content up until the more tag, but strip out images and object tags you can try this. In the home page and/or archive templates, you’ll need to replace the_excerpt or the_content with the following:

$content = get_the_content('');
$content = apply_filters('the_content', $content);
echo wpt_strip_content_tags($content);

Then you’ll need to add the function:

/* Custom Excerpt Function */

function wpt_strip_content_tags($content) {
	$content = strip_shortcodes($content);
	$content = str_replace(']]>', ']]>', $content);
	$content = preg_replace('/<img[^>]+./','',$content);
	$content = preg_replace('%<object.+?</object>%is', '', $content);
	return $content;
}

Purely Through a Function

I also wrote a way to do this entirely through a function. It seems like a lot of code to achieve one little thing, and I’m not sure what it would do to performance- but I thought I’d post it here anyways to get feedback.

This code will look to see if an excerpt has been entered manually, if so, that gets displayed. If not, it will pull the full content, split it at the more mark, filter the content to remove images and object tags, then add back in paragraphs.

For this to work in practice, it would probably need one more conditional to just display full unfiltered content if you don’t have an excerpt or a more tag– or truncate it to display the amount of words you choose.

// Custom Excerpts

add_filter('the_content', 'wpt_custom_excerpts');

function wpt_custom_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, display until more tag without images or objects
		else :
			$morestring = '<!--more-->';
			$explodemore = explode($morestring, $post->post_content);
			$content = $explodemore[0]; // Get content before the more-tag
			$content = strip_shortcodes($content);
			$content = str_replace(']]>', ']]&gt;', $content);
			$content = preg_replace('/<img[^>]+./','',$content);
			$content = preg_replace('%<object.+?</object>%is', '', $content);
			$content = nl2br($content); // Because paragraphs are being filtered out
		endif;
	endif;

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

}

5 Responses

  1. Thanks for the explanation. Very clear and easy to understand. As the years pass- my love affair with wordpress grows…and with such cool and simple additions like this…it’s hard to resist!

  2. I like the thinking behind this… Isn’t there a global $more variable that you can check for, though, rather than all the conditonals you’re checking for? Just seems like this would be simpler to work with core, instead of trying to replicate it’s functionality.

  3. Ha. I seriously laughed at the phrase “mullet loop”. No, I hear what you’re saying. I was just talking about this line:

    if(is_front_page() || is_archive() || is_search()) :

    Rather than try and come up with all the reasons someone might want to use a full post, I just thought you could work with the existing $more variable, which is set to 1 on single posts and pages, and usually not set anywhere else.


    global $more; if (!$more) :

    Otherwise, I like the function and am going to include it in some of my projects. Thanks.

Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>