How to auto-trim the_content()?
There are two “official” methods of how to display Post excerpt: by using built-in text editor “Insert More tag” (Ctrl+Shift+T) or WordPress function named “the_excerpt()”. By the way, Post excerpt is actually a chunk of text containing that “MORE” link at the end. None of these two offer an elegant solution – that’s my personal opinion.
The first one is partially OK because it allows users to insert “MORE” link at desired position in text and HTML doesn’t get stripped on front-end. However, people often forget to insert more tag or hate counting words in order to keep Post excerpt consistent regarding the amount of text.
The second method is usually built into certain template file (the_excerpt() function) and is supposed to automatically trim Post content to 55 words. It sounds fine but you gotta know that this function strips down all of HTML tags including images.
So how about to simply trim the_content() to desired number of words, keep all of HTML tags and no need for More tag insertion at all?
Here’s the function I use for all of my themes and it works perfectly…
<?php
function trim_the_content( $the_contents = '', $read_more_tag = '...READ MORE', $perma_link_to = '', $all_words = 45 ) {
// make the list of allowed tags
$allowed_tags = array( 'a', 'abbr', 'b', 'blockquote', 'b', 'cite', 'code', 'div', 'em', 'fon', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'label', 'i', 'p', 'pre', 'span', 'strong', 'title', 'ul', 'ol', 'li', 'object', 'embed', 'param' );
if( $the_contents != '' && $all_words > 0 ) {
// process allowed tags
$allowed_tags = '<' . implode( '><', $allowed_tags ) . '>';
$the_contents = str_replace( ' ]]>', ' ]]>', $the_contents );
$the_contents = strip_tags( $the_contents, $allowed_tags );
// exclude HTML from counting words
if( $all_words > count( preg_split( '/[\s]+/', strip_tags( $the_contents ), -1 ) ) ) return $the_contents;
// count all
$all_chunks = preg_split( '/([\s]+)/', $the_contents, -1, PREG_SPLIT_DELIM_CAPTURE );
$the_contents = '';
$count_words = 0;
$enclosed_by_tag = false;
foreach( $all_chunks as $chunk ) {
// is tag opened?
if( 0 < preg_match( '/<[^>]*$/s', $chunk ) ) $enclosed_by_tag = true;
elseif( 0 < preg_match( '/>[^<]*$/s', $chunk ) ) $enclosed_by_tag = false; // get entire word if( !$enclosed_by_tag && '' != trim( $chunk ) && substr( $chunk, -1, 1 ) != '>' ) $count_words ++;
$the_contents .= $chunk;
if( $count_words >= $all_words && !$enclosed_by_tag ) break;
}
// note the class named 'more-link'. style it on your own
$the_contents = $the_contents . '' . $read_more_tag . '';
// native WordPress check for unclosed tags
$the_contents = force_balance_tags( $the_contents );
}
return $the_contents;
}
?>
Where to paste the above code?
If your WP theme doesn’t contain “functions.php” file – create one and simply paste. Otherwise use existing “functions.php”.
How to use the above function?
Many of you will not need an additional explanation but here it is just for case….
Which template file uses More tag? As far as I know, the list includes “category.php”, “index.php”, “search.php”, “archive.php”, “tag.php” or any other custom made template file. It’s not a must – of course, but rather your choice. So if you decide to apply automatic content trim, standard call to a WP function the_content() will not do the job. You’ll have to add several extra lines of code instead:
<?php
// here's the point where we are about to display Post excerpt
$perma_link = get_permalink( $post->ID ); // current Post permalink
$content = get_the_content(); // save entire content in variable
$content = apply_filters( 'the_content', $content ); // WP bug fix
$content = str_replace( ']]>', ']]>', $content ); // ...as well
echo trim_the_content( $content, __( "READ MORE", "sofa_memento" ), $perma_link, 55 ); // trim to 55 words
?>
USER COMMENTS ( 0 )
Follow Comments via RSS feed. Trackback Comments from your website.