Note: The suggested method will be updated from time to time after collecting more information from the asker. The current suggested method assumed some conditions.
- The following code is for putting in
functions.php
, if you are writing a plugin. Please remember to change the callback and write in plugin mode. For more about plugin writing, please refer to Plugin Handbook
This example is assumed
- the site domain is changed
- the whole url structure is same, if not, then this solution is not suitable
Case 1
If you have an old site, and want to redirect any page to new site with just difference domain name. You may try this
add_action( 'init', 'q363843_global_redirect' );
function q363843_global_redirect() {
// do redirect before sending header
if ( isset( $_SERVER['HTTP_HOST'] ) ) {
$requested_url = is_ssl() ? 'https://' : 'http://';
$requested_url .= $_SERVER['HTTP_HOST'];
$requested_url .= $_SERVER['REQUEST_URI'];
}
// @ means surpass warning, for it is used in WordPress Core file like canonical.php, so I follow, for development, it is better to leave it
// $original = @parse_url( $requested_url );
$original = parse_url( $requested_url );
// change only domain, assume the new site is same in structure
// 'something-else' must be different host for same host, an over simplified redirect without well checking will result in redirect loop, so beware
wp_redirect( $original['scheme'] . '://' . 'something-else' . $original['path'] );
// exit will terminate the script immediately after redirect is called,
// this will ensure that the current script will be stopped here and prevent from infinite loop
// if use return here, it means finish the function but script is possible to continue in some occasions...
exit();
}
importantance of exit()
Putting exit() after redirect is WordPress Core practice used in such as canonical.php, ms-functions.php, pluggable.php and you name it.
...Terminates execution of the script...
about return keyword
...return returns program control to the calling module.
Case 2
If you want to check the post-name of the site, you may consider the following, it is similar to case 1, only that you need to check the post-name.
This is one of the possibilities, mechanism:
- (Old site) do the redirect first
- because the new site is of different structure, just redirect to http://new-domain.com/post-name first
- (New site) use
query
hook orpre_get_posts
to analyse and get the right post id.query
filter is one of the earliest filters that handle the query. Together with the help of url_to_postid, you can find the post id from the redirect link.
My personal worked experience and preference, I choose query
filter and rebuild the query. The reason to use query
because
- it manipulates the query before putting into $wp_query, so there is no $post is created yet, the global $post at this point is null.
- it is before any 404 being check and set
- if set it right and understand it, I could resolve any 404 issue.
Assumption:
- post-name exist in both side and remain the same
// In the old site functions.php
add_action( 'init', 'q363843_global_redirect' );
function q363843_global_redirect() {
// do redirect before sending header
if ( isset( $_SERVER['HTTP_HOST'] ) ) {
$requested_url = is_ssl() ? 'https://' : 'http://';
$requested_url .= $_SERVER['HTTP_HOST'];
$requested_url .= $_SERVER['REQUEST_URI'];
}
$original = parse_url( $requested_url );
// your extract post-name mechanism
$redirect = $original['scheme'] . '://' . 'new-domain' . '/post-type/post-name'; // <-- add post type if you know it, increase the matching possibility for url_to_postid()
wp_redirect( $redirect );
exit();
}
// In the new site functions.php
add_filter( 'query', 'q363851_check_query_from_url');
function q363851_check_query_from_url( $query ) {
// check and build the URL
if ( isset( $_SERVER['HTTP_HOST'] ) ) {
$requested_url = is_ssl() ? 'https://' : 'http://';
$requested_url .= $_SERVER['HTTP_HOST'];
$requested_url .= $_SERVER['REQUEST_URI'];
}
// try to fetch post id using built-in function
$post = url_to_postid( $requested_url );
var_dump($post); // check to see
// here, you could either build the URL, redirect and exit this script (lazier) OR
// you modify the query so that WordPress think that the post type and page id is valid for next step
return $query;
}