I set up this rule (in functions.php)

function custom_rewrite_basic() {
add_action('init', 'custom_rewrite_basic');

expecting it to redirect www.domain.com/episode/postname/2/ over to www.domain.com/episode/postname/transcript/ but it's still going to /2/.

Interestingly enough, if I type in www.domain.com/episode/postname/transcript/ it still works, but does a redirect to /2/.

I have installed the Rewrite Analyzer plugin and it's not giving me any errors... my post type is "episodes" and the slug/url is "episode"

Can anyone please guide me? Eternally grateful... Sarah

1 Answer 1


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 );

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' );
  • You are amazing! This works perfectly. Looks like I was missing a lot ;) Thanks so much!
    – Sarah
    Commented Mar 12, 2015 at 20:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.