Set font size automatically according to number of words in post

Filter 'the_content', count the words, and add the markup you need. You should not use str_word_count() because it has issues with numbers and utf-8.

So let’s start with a word count function:

/**
 * Alternative for str_word_count().
 *
 * @link http://toscho.de/2012/php-woerter-zaehlen/
 * @param string $str
 * @return int Number of words
 */
function t5_word_count( $str )
{
    // We do not want to count markup
    $text = strip_tags( $str );
    // no leading and trailing white space
    $text = trim( $text );
    // take multiple white spaces as one
    // Add one space to get an almost exact match
    $word_count = preg_match_all( '~\s+~', "$text ", $m );

    return (int) $word_count;
}

Now the filter function:

// Hook in very late to let other filters (shortcodes and such)
// do their work first.
add_filter( 'the_content', 't5_content_word_count', 999 );

/**
 * Add a <div> with a special class to the content.
 *
 * @param string $content
 * @return string
 */
function t5_content_word_count( $content )
{
    $words = t5_word_count( $content );
    $class="default";
    // max 100 words
    $words < 101 && $class="100";
    // max 50 words
    $words < 51  && $class="50";
    return "<div class="word-count-$class">$content</div>";
}

Instead of inline styles which are very bad on mobile devices or printed pages I have chosen a class.

In your stylesheet you can now style these classes:

.word-count-default 
{
    font-size: 1em;
}
.word-count-100
{
    font-size: 1.1em;
}
.word-count-50 
{
    font-size: 1.2em;
}

Be aware that the filter works on single pages of a post only. If you have split a post into multiple parts with <!--nextpage--> you may get different classes for different pages of that post.

Update

To insert the div when a post is saved do not filter 'the_content', but 'wp_insert_post_data'. And you need a third function for this:

add_filter( 'wp_insert_post_data', 't5_count_words_on_insert', 999 );

/**
 * Add the font size div on post insert.
 *
 * @wp-hook wp_insert_post_data
 * @param   array $data
 * @return  array
 */
function t5_count_words_on_insert( $data )
{
    '' !== $data['post_content']
        && FALSE === strpos(
                stripslashes( $data['post_content'] ),
                "<div class="word-count-"
            )
        && $data["post_content'] = t5_content_word_count( $data['post_content'] );

    return $data;
}

See /wp-includes/post.php function wp_insert_post() for details.

I do not recommend this solution. You cannot use <!--nextpage--> now anymore because you would end up with an unclosed <div> on the first page.

Leave a Comment