Change page /2 to /transcript with a Rewrite

The rewrite API won’t redirect – it just “maps” URL structures to query strings – you’ll need to do this yourself.

First things first, fix that rewrite rule:

'episode/([^/]+)/transcript'; // Matches anything that follows transcript, not what we want!
'episode/([^/]+)/transcript/?$'; // Matches only "episode/name/transcript", optionally with a trailing slash

Now bring in a helper function:

/**
 * Get transcript URL.
 *
 * @param   int     $post_id
 * @return  string
 */
function wpse_180990_get_transcript_url( $post_id ) {
    return trailingslashit( get_permalink( $post_id ) ) . user_trailingslashit( 'transcript' );
}

And to perform the redirect:

/**
 * Force "episode/postname/2" to canonicalize as "episode/postname/transcript".
 */
function wpse_180990_redirect_transcript() {
    global $wp;

    if ( is_singular( 'episodes' ) && get_query_var( 'page' ) === 2 && $wp->matched_rule !== 'episode/([^/]+)/transcript/?$' ) {
        $url = wpse_180990_get_transcript_url( get_queried_object_id() );
        wp_redirect( $url );
        exit;
    }
}

add_action( 'template_redirect', 'wpse_180990_redirect_transcript' );

If it’s page 2 of a single episode, but our custom rewrite wasn’t the request URI, send them on their way to /transcript.

Now to address the redirect you’re getting at the moment (/transcript to /2). WordPress has a handy function redirect_canonical(), which attempts to keep all requests as “singular” (canonical) as possible. Trouble is, it’s sometimes to smart for its own good.

In your case, it detects the same conditions are true (page 2 of a single episode), but simply deems the current request the “wrong” one and redirects to the “right” one.

Let’s tell it not to do that:

/**
 * Override {@see redirect_canonical()}.
 *
 * @see wpse_180990_force_transcript()
 *
 * @param   string  $url
 * @return  string
 */
function wpse_180990_transcript_canonical( $url ) {
    if ( is_singular( 'episodes' ) && get_query_var( 'page' ) === 2 )
        $url = wpse_180990_get_transcript_url( get_queried_object_id() );

    return $url;
}

add_filter( 'redirect_canonical', 'wpse_180990_transcript_canonical' );

Leave a Comment