Splitting the_content() by size?

The function assumes wpautop filter on the_content is sitting at priority 10, where WP adds it. If, for any reason, it has been moved at another priority, the filter below should be adjusted to happen after wpautop.

The function filters the_content if we are in frontend and we are on a singular post/page (feel free to adjust this so it applies where you actually need it) and, ofocurse, it checks if this particular post has the quote custom field.

If all of the above, it splits the content in two halfs and replaces the first occurence of </p> from the second half with </p> + $quote. You will also note that i’m deducting 4 from $split_point if $content length is bigger than 8. This is done to include cases where the actual split happens inside an ending </p>.

add_filter('the_content', 'split_by_quote', 11);
function split_by_quote($content) {
    global $post;
    $custom_meta_key = 'quote';
    $tag             = 'blockquote';
    if ((!is_admin()) && is_singular(array('post', 'page')) // adjust to your needs
    && $quote = get_post_meta($post->ID, $custom_meta_key, true)) {
        $split_point = intval(strlen($content)/2);
        $split_point = strlen($content > 8) ? $split_point - 4 : $split_point;
        $first_half  = substr($content, 0 , $split_point);
        $second_half = substr($content, $split_point);
        $second_half = preg_replace(
            '|<\/p>|',
            "</p><{$tag}>".$quote."</{$tag}>",
            $second_half,
            1
        );
        $content     = $first_half.$second_half;
    }

    return $content;
}

This should go inside functions.php of your theme, preferably a child theme. If you only want it in a specific post or page, just add is_page({id_here}) or is_single({id_here}) to the condition of the filter and remove is_singular().

When run against a content that does not have a </p> in the second half, it will not output the quote, but this basically means that wpautop filter was not run on that content. So adding:

remove_filter('the_content', 'wpautop');
add_filter('the_content', 'wpautop');

in your functions.php should make it work (output the quote).

If all your content is in one big </p>, the quote will be output after the content.

Another thing to check for is wether you’re outputing inside another tag of the same type as $tag (you don’t want a blockquote inside another blockquote). The function above does not make that check.