Make Google index the entire post if it is separated into several pages

The basic problem for a script solution is: rel_canonical does not offer any useful filter. So we have to replace that function:

remove_action( 'wp_head', 'rel_canonical' );
add_action( 'wp_head', 't5_canonical_subpages' );

The next problem: $GLOBALS['numpages'] is empty before setup_postdata(). We could call that function already here, but it might have side-effects.

Here is a solution that adds correct prev/next links too, and it prevents conflicting relations caused by adjacent_posts_rel_link_wp_head. We have too hook into wp_head not later than priority 9 to deactivate the latter hook.

remove_action( 'wp_head', 'rel_canonical' );
add_action(    'wp_head', 't5_canonical_subpages', 9 );

/**
 * Extend version of the native function rel_canonical()
 *
 * @wp-hook wp_head
 * @return  void
 */
function t5_canonical_subpages()
{
    if ( ! is_singular() )
        return;

    if ( ! $id = $GLOBALS['wp_the_query']->get_queried_object_id() )
        return;

    $post = get_post( $id );
    setup_postdata( $post );

    # let WordPress do all the work
    if ( empty ( $GLOBALS['page'] ) )
        return rel_canonical();

    $permalink = get_permalink( $id );
    $canonical = t5_page_permalink( $permalink, $GLOBALS['page'] );
    echo "<link rel="canonical" href="https://wordpress.stackexchange.com/questions/87514/$canonical" />";

    # next and prev links
    if ( 1 < $GLOBALS['page'] )
    {
        $prev = t5_page_permalink( $permalink, $GLOBALS['page'] - 1 );
        print "<link rel="prev" href="$prev" />";
    }

    if ( isset ( $GLOBALS['numpages'] ) && $GLOBALS['page'] < $GLOBALS['numpages'] )
    {
        $next = t5_page_permalink( $permalink, $GLOBALS['page'] + 1 );
        print "<link rel="next" href="$next" />";
    }

    # avoid conflicting pev/next links
    remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head' );
}

/**
 * Helper to get correct permalinks for sub-pages.
 *
 * @param  string $permalink
 * @param  int    $page
 * @return string
 */
function t5_page_permalink( $permalink, $page )
{
    if ( 1 == $page )
        return $permalink;

    # no pretty permalinks
    if ( '' === get_option( 'permalink_structure' ) )
        return add_query_arg( 'page', $page, $permalink );

    return $permalink . user_trailingslashit( $page, 'single_paged' );
}

Leave a Comment