WordPress Snippet: ALWAYS show a “read more” link using the_excerpt()

Anyone who has developed a custom theme for WordPress is probably familiar with the inconsistencies of dealing with excerpts, sometimes called “more teasers”. The problem stems from the ability for the blog/site owner to be able to create excerpts in three ways:

  1. Manually type a specific excerpt using the “excerpt” data field
  2. Use the nifty “more tag” to indicate a beginning portion of the article as the excerpt-more-teaser
  3. Or do nothing at all and have them auto generated from the first few hundred characters or so

And then as the theme developer you have two main (default) ways of displaying these three items:

  1. Explicitly choose to show either the manually entered excerpt or the auto generated excerpt if that doesn’t exist
  2. Simply allow the entire content to be displayed IF the nifty <!--more--> tag doesn’t exist

The end result is also three different ways the excerpt will or will not provide some kind of indication that the excerpt has been truncated (if it has) and include a link to the entire article if an excerpt only is being displayed by any means.

If the excerpt is auto generated (from the first X characters of the post content with all formatting stripped) an ellipsis is added to indicate that it has been truncated, but if it is, then no “read more” permalink is provided. If the blog/site owner manually enters an excerpt, then the excerpt is displayed as entered with formatting if the site/blog owner included formatting (though automatic paragraphs and line breaks happen) and still no permalink “read more”. Or if they use the <!--more--> tag and your theme isn’t designed for that then the excerpt is auto generated. Or, more likely they use the <!--more--> tag and your theme outputs exactly what is expected along with a convenient “read more” link right where you’d probably like one to be.

The following code simply makes sure that the text/link you use in the first function the_excerpt_read_more_link() is always shown at least when using the_excerpt() regardless of whether the excerpt is auto generated or manually entered.

/**
 * Always add a "read more" link to ALL excerpts (if there is more to read ;)
 * and still check to add elipsis if the excerpt was truncated
 *
 * Maintains consistency between manually written excerpts
 * and WP auto-generated excerpts using the_excerpt()
 *
 * These (2) filters use (3) functions
 * @uses    the_excerpt_read_more_link()
 * @uses    the_excerpt_always_show_read_more()
 * @uses    the_excerpt_was_truncated_so_format()
*/
add_filter( 'get_the_excerpt', 'the_excerpt_always_show_read_more', 9 ); // Must happen before wpauotp gets a hold of it
add_filter( 'excerpt_more', 'the_excerpt_was_truncated_so_format' );

/**
 * The custom text in the "read more" permalink
 * Abstracted so it can also be used in the_content() to make ALL excerpts consistent
*/
function the_excerpt_read_more_text_for_link() {
    return 'read on &amp;raquo;';
}

/**
 * The permalink / read more output we will use on all the_excerpt output
*/
function the_excerpt_read_more_link() {
    global $post;
    return ' &lt;span&gt;| &lt;a href="'. get_permalink($post-&gt;ID) . '"&gt;' . the_excerpt_read_more_text_for_link() .  '&lt;/a&gt;&lt;/span&gt;';
}

/**
 * Check to see if the current post in the loop was manually written
 * and add our link if it was. Manually written excerpts are formatted
 * so we have to add this here if we want it inline with the last
 * paragraph/element. Manually written excerpts are never truncated so no worries.
*/
function the_excerpt_always_show_read_more() {
    global $post;
   // Only manually add the link if the excerpt was manually written
   // otherwise WP generated excerpts will never trigger
   if ( !empty($post-&gt;post_excerpt) )
       return $post-&gt;post_excerpt . the_excerpt_read_more_link();
   else
   return $post-&gt;post_excerpt;
}

/**
 * If WP truncates auto generated excerpt then add this plus our read more permalink
*/
function the_excerpt_was_truncated_so_format() {
    return '[...]' . the_excerpt_read_more_link();
}

And if you want to have it be the same when using the_content() then you can just reuse your excerpt link function one more time:

the_content( the_excerpt_read_more_text_for_link() )

This example isn’t necessarily intended to be used as is but simply demonstrates one of many ways to think about making your WordPress theme development more consistent. Of course I would prefer for the_excerpt() to accept a $read_more_link_text parameter that would show up regardless of truncation or how the excerpt was created. For that matter the_excerpt('Read more...'); would ideally first check for a manually entered excerpt, THEN check if the <!--more--> tag was used and use that if so, and LASTLY do the auto generate.

But then I guess I could get off my ass and submit a patch request and hope it gets in. So really I have no one to blame except myself. And really is it in the developers best interest to have WordPress be so easy to code and manipulate that the average blog user could figure this stuff out without knowing how to write PHP? Probably not, but it would be the right thing to do. Alas.

Leave a Reply

Your email address will not be published. Required fields are marked *

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>