Render a different post/template from within the template_include action?

This was a bit tricky to solve your problem.
the template_include filter executed after the main query processed the current request. If you can filter the current request (query_vars) and update it accordingly then WordPress will display any post/page you wanted to… Simply filter the query_vars with the request filter. Check the following snippet. But doing this might have a bad effect on SEO.

add_filter( 'request', function( $query_vars ) {
    if( is_admin() ) return $query_vars;
    $_post = null;
    // find the queried post
    if( isset( $query_vars['post_type'], $query_vars['your-post-type'] ) && $query_vars['post_type'] == 'your-post-type' ) {
        // $query_vars['your-post-type'] will contains the post slug
        $_post = get_page_by_path( $query_vars['your-post-type'], OBJECT, $query_vars['post_type'] );
    } else if( isset( $query_vars['p'] ) ) {
        $_post = get_post( $query_vars['p'] );
        if( $_post != 'your-post-type' ) $_post = null;
    }
    if( $_post ) { // post found
        // get the redirect to page id
        $custom_page_id = get_post_meta( $_post->ID, 'custom_page_id', true );
        $custom_page = get_post( $custom_page_id );
        if( $custom_page ) { // valid page/post found.
            // set the query vars to display the page/post
            $query_vars[$custom_page->post_type] = $custom_page->post_name;
            $query_vars['name'] = $custom_page->post_name;
            $query_vars['post_type'] = $custom_page->post_type;
        }
    }
    return $query_vars;
}, 10 );

Leave a Comment