Here are a few filters I rely on for limiting word and character counts. The first is character based but only splits between words.
function nicetrim( $string ) {
// limit the length of the given string to $MAX_LENGTH char
// If it is more, it keeps the first $MAX_LENGTH-3 characters
// and adds "..."
// It counts HTML char such as á as 1 char.
$MAX_LENGTH = 50;
if ( strlen( $string ) <= $MAX_LENGTH ) {
return $string;
}
$s2 = substr( $string, 0, $MAX_LENGTH );
$s3 = preg_split( "/\s+(?=\S*+$)/", $s2 );
$s4 = $s3[0];
$s4 .= "…";
return $s4;
This one excepts a word count variable and looks for your more tag. It also strips out any html before counting then adds it back.
function trim_the_bio( $the_bio = '', $all_words = 25, $more_link ='' ) {
$the_bio = strange_chars ( $the_bio );
$html = '</span><a id="more-link" href="#">More ↓</a><a style="display:none;" id="less-link" href="#">Less ↑</a>';
// Removes any tags not in the allowed tags array
$allowed_tags = array ( 'a', 'abbr', 'b', 'blockquote', 'b', 'cite', 'code', 'div', 'em', 'fon', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'i', 'img', 'label', 'i', 'pre', 'span', 'strong', 'title', 'ul', 'ol', 'li', 'object', 'embed', 'param' );
if ( $the_bio != '' && $all_words > 0 ) {
// process allowed tags
$allowed_tags = '<' . implode( '><', $allowed_tags ) . '>';
$the_bio = str_replace( ' ]]>', ' ]]>', $the_bio );
$the_bio = strip_tags( $the_bio, $allowed_tags );
if ( 20 < count ( preg_split ( '/[\s]+/', strip_tags ( $the_bio ), - 1 ) ) && $more_link != '' ) $flag = true; else $flag = false;
// exclude HTML from counting words
if ( $all_words > count( preg_split( '/[\s]+/', strip_tags( $the_bio ), -1 ) ) ) if ( $flag == false ) { return $the_bio; } else { return $the_bio.$html; }
// count all
$all_chunks = preg_split( '/([\s]+)/', $the_bio, -1, PREG_SPLIT_DELIM_CAPTURE );
$the_bio = '';
$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_bio .= $chunk;
if ( $count_words >= $all_words && !$enclosed_by_tag ) break;
}
// Close any unclosed tags
$the_bio = force_balance_tags( $the_bio );
}
// Throw it down...
if ( $more_link != '' ) return $the_bio . $html;
else return $the_bio;
}