Programmatically inserting page breaks

Overriding the default page breaking – with external content parts

The page breaking takes place in the WP_Query::setup_postdata() method, when we call the_post() in the loop.

The page parts are stored in the global $pages array and fetched with get_the_content() function.

This happens all before the the_content filter is applied to the content.

We can modify this default page breaking, with our own get_the_content() wrapper.

Let’s assume we got this in our theme template:

// Display
the_content();

// Paging
wp_link_pages();

Here below are two ways to modify the page breaking, using some external content parts.

1) Modification of a child theme

We replace this, in the corresponding child theme, with:

// Setup our content parts
$parts = [ get_the_content(), 'Part Two', 'Part Three', 'Part Four' ];

// Display
if( function_exists( 'get_the_content_part_wpse194155' ) )
    echo apply_filters( 'the_content', get_the_content_part_wpse194155( $parts ) );
else
    the_content();

// Paging
wp_link_pages();

2) Modification with a filter

We could also use the the_content filter. Example:

! is_admin() && add_filter( 'the_content', function( $content )
{
    if( ! in_the_loop() || ! function_exists( 'get_the_content_part_wpse194155' ) )
        return $content;

   // Setup our content parts
    $parts = [ $content, 'Part Two', 'Part Three', 'Part Four' ];

    // Display
    return get_the_content_part_wpse194155( $parts );

} );

Note that here we just use static content parts for demonstration. In general you would want to have different content parts for each post.

Helper function

Our custom wrapper is defined as:

/**
 * Modify globals to support page breaks between given content parts
 *
 * @param  array  $parts Array of content parts 
 * @return string|null   A single content part
 */

function get_the_content_part_wpse194155( array $parts )
{
    global $page, $pages, $multipage, $numpages;

    // No paging needed
    if( count( $parts ) <= 1 )
        return array_pop( $parts );

    // Init
    $out="";
    $break = '<!--nextpage-->';
    $page  = (int) get_query_var( 'page' );

    // Loop - add page breaks between parts
    foreach( (array) $parts as $part )
        $out .= $part . $break;

    // Remove the last empty page break
    if( count( $parts ) > 0 )
        $out = mb_substr( $out, 0, -1 * strlen( $break ) );

    // Adjust the globals
    $pages     = explode( $break, $out );
    $page      = ( $page > count( $pages ) || $page < 1 ) ? 1 : $page;
    $numpages  = count( $pages );
    $multipage = 1;    

    return $pages[$page-1];
}

Leave a Comment