Why?
I think the reason why
a) domain.com/123
is not redirected back to
b) domain.com/123/post-slug
with the /%post_id%/%postname%/
permalinks settings, is that the matched rule is:
[matched_rule] => ([0-9]+)(/[0-9]+)?/?$
You can get that information from the global $wp
object.
There are other useful informations in $wp
available after the wp
action:
Example (post): domain.com/123/post-slug/
[query_vars] => Array
(
[p] => 123
[page] =>
[name] => post-slug
)
[query_string] => p=123&name=post-slug
[request] => 123/post-slug
[matched_rule] => ([0-9]+)/([^/]+)(/[0-9]+)?/?$
[matched_query] => p=123&name=post-slug&page=
[did_permalink] => 1
Example (post): domain.com/123/
:
[query_vars] => Array
(
[p] => 123
[page] =>
)
[query_string] => p=123
[request] => 123
[matched_rule] => ([0-9]+)(/[0-9]+)?/?$
[matched_query] => p=123&page=
[did_permalink] => 1
Example (page): domain.com/hello-world/
:
[query_vars] => Array
(
[page] =>
[pagename] => hello-world
)
[query_string] => pagename=hello-world
[request] => hello-world
[matched_rule] => (.?.+?)(/[0-9]+)?/?$
[matched_query] => pagename=hello-world&page=
[did_permalink] => 1
Redirect example:
Here’s an example how to redirect from a) to b) using information from the global $wp
object:
add_action( 'wp', function(){
global $wp;
if( is_numeric( $wp->request ) && empty( $wp->query_vars['page'] ) )
{
wp_redirect( get_permalink( absint( $wp->request ) ), 301 );
exit();
}
});
i.e. we redirect when the page query varaible is not set and the request is numeric.
ps: I just want to mention that this is using the wp
action, that is fired rather late, but before the template_redirect
action, allowing the redirect possible.
I also tried to come up with an example that is not using the $_SERVER
variable 😉
Hope this helps.