I need to build a offline page and first idea was to simply get desired page ID and do wp_redirect but that leaves a URL of the page to redirect to.

function _action_offline_mode( $template  ){

    if( is_admin()){

    $offline    = get_option('offline','inactive');
    $off_page   = get_option('off_page',null);

    if('active' == $offline && !empty($off_page)){

        $user           = wp_get_current_user();
        $allowed_roles  = array('administrator');       
        $off_page_link  = get_permalink($off_page[0]);

        if( !array_intersect($allowed_roles, $user->roles ) && ( get_the_ID() != $off_page[0] ) ){

add_action( 'template_redirect', '_action_offline_mode');

leaves in browser


than I was thinking about doing template_redirect but that is not overriding the actual query page ID and leaves me with undesired options. Also tried pre_get_posts but could not get it to work properly.

Does anyone know a decent way to tell WordPress to display a specific page by ID without using custom template and with using built in hooks?

Example you are on a page by ID 10 , add function to show page by ID 80 instead with all its options.

Please note that show other page content like this here Get the content of a specific page (by ID)

leaves main query untouched so main query will still pull all page data from page with ID 10 , but I need it to show page by ID 80 and main query to have data from page ID 80.

Reason for this is because each page can have some custom settings which are than pulled by the page ID and if the query page ID is different from what is displayed I end up having wrong options.

1 Answer 1


You could do this a few different ways, depending on what's happening in the template and how you are able to identify which page you want to override.

1. Simple method with pre_get_posts:

This will mostly work, but the queried object will still contain the old page, however, using get_the_ID() in the template to load page data will return the correct ID and enable you to load data from the target page.

function wpd_switch_page( $query ){
    if( $query->is_page( 42 ) && $query->is_main_query() ) {
        $query->set( 'page_id', 23 );
add_action( 'pre_get_posts', 'wpd_switch_page' );

2. Using simple request filter with page name:

This will correctly set the queried object, so body classes and such will contain the correct ID, get_queried_object_ID() will return the ID of the target page. In this case though, you have to know the pagename of the source and target pages, not ID:

function alter_the_query( $request ) {
    if( isset( $request['pagename'] ) && 'source-page' == $request['pagename'] ){
        $request['pagename'] = 'target-page';
    return $request;
add_filter( 'request', 'alter_the_query' );

3. Using request filter with page ID:

If you parse the query first, you can check the source page ID instead of name. You have the option of then setting pagename as above, or you do it by page ID if you'd like:

function alter_the_query( $request ) {
    $dummy_query = new WP_Query();
    $dummy_query->parse_query( $request );

    if ( $dummy_query->is_page( 42 ) ){
        unset( $request['pagename'] );
        $request['page_id'] = 23;
    return $request;
add_filter( 'request', 'alter_the_query' );
  • bless your heart! request works fine , all I need to check if we are in maintenance mode and if yes set the page id! thank you!
    – Benn
    May 30, 2017 at 16:57

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.