i make migration plugin from specific script to wordpress, but i have a problem on redirect old urls to new one
old urls is like book.php?view=12a34b56
and i want redirect it to book/12a34b56
i try to make it by add_rewrite_rule like this
init function >
add_rewrite_rule(
'^book.php\?view=([^&]*)&?',
'index.php?name=$matches[1]',
'top'
);
but rewrite rule not detect query args i don't know why, so i'm changed the method to
query_vars function >
array_push($vars, 'view');
pre_get_posts function >
if (!is_admin() && is_main_query() && get_query_var('pagename') === 'book.php' && get_query_var('view') != '') {
$query->set('name', get_query_var('view'));
// after redirect to new url, view arg not removed
// new url be like this book/12a34b56/?view=12a34b56
// i try to remove view arg in url after set query but it's still not removed
$query->set('view', false);
set_query_var('view', false);
unset($_GET['view']);
}
this method work perefectly but i still have one problem like i say in code comments
new url be like book/12a34b56/?view=12a34b56
,
how i can remove ?view=12a34b56
after set post name, or method to detect query args on add_rewrite_rule that will be great.
NOTE : i do not want edit .htaccess directly
i make migration plugin from specific script to wordpress, but i have a problem on redirect old urls to new one
old urls is like book.php?view=12a34b56
and i want redirect it to book/12a34b56
i try to make it by add_rewrite_rule like this
init function >
add_rewrite_rule(
'^book.php\?view=([^&]*)&?',
'index.php?name=$matches[1]',
'top'
);
but rewrite rule not detect query args i don't know why, so i'm changed the method to
query_vars function >
array_push($vars, 'view');
pre_get_posts function >
if (!is_admin() && is_main_query() && get_query_var('pagename') === 'book.php' && get_query_var('view') != '') {
$query->set('name', get_query_var('view'));
// after redirect to new url, view arg not removed
// new url be like this book/12a34b56/?view=12a34b56
// i try to remove view arg in url after set query but it's still not removed
$query->set('view', false);
set_query_var('view', false);
unset($_GET['view']);
}
this method work perefectly but i still have one problem like i say in code comments
new url be like book/12a34b56/?view=12a34b56
,
how i can remove ?view=12a34b56
after set post name, or method to detect query args on add_rewrite_rule that will be great.
Share Improve this question edited Oct 5, 2020 at 6:38 Boyzen asked Oct 4, 2020 at 21:56 BoyzenBoyzen 235 bronze badgesNOTE : i do not want edit .htaccess directly
1 Answer
Reset to default 1It doesn't work with add_rewrite_rule()
because of the ?view=
part in the URL (it's the first parameter for the function) — i.e. WordPress strips that query string part, hence it's not included when WordPress finds a matching rewrite rule.
how I can remove
?view=12a34b56
after set post name
You can't (not on the same page), because that is a query string in the request URL which PHP reads from upon loading the page, and the browser already "put" the URL in the address bar.
But because I believe you want a 301 (permanent) redirect whereby the URL in the browser's address bar changes, then you can easily achieve that redirect via the parse_request
hook — you could also use the init
hook, but with parse_request
, WordPress already parses the request path (e.g. https://example/this-path/
), so we can simply read from the parsed data, i.e. the $wp->request
below.
So this should work for you, but make sure to remove that pre_get_posts
code from your file:
add_action( 'parse_request', 'wpse_375940' );
function wpse_375940( $wp ) {
if ( 'book.php' === $wp->request &&
! empty( $_GET['view'] )
) {
$query = new WP_Query( [
'name' => $_GET['view'],
'fields' => 'ids',
] );
if ( ! empty( $query->posts ) &&
$url = get_permalink( $query->posts[0] )
) {
// Or use 302. It's up to you to decide.
wp_redirect( $url, 301 );
exit;
}
}
}