Auto-Redirect Root-Level Posts on Permalink Change
The use case here is when you’ve made the decision to switch your blog post URLs from being at the root-level (e.g. /hello-world
) to using a base path (e.g. /blog/hello-world
).
Typically, you’d have to carefully map out the redirects and set them up in your .htaccess
file, a WordPress plugin, or in your web host’s redirect manager. Creating a generic regex solution won’t work since pages also are at the root-level.
Here is some drop-in code that will automatically detect 404’s and will redirect these root-level posts to the new URL:
<?php
add_action( 'template_redirect', function () {
/**
* @var WP $wp
*/
global $wp;
/**
* @var WP_Query $wp_query
*/
global $wp_query;
if ( $wp_query->is_404() ) {
$query = new WP_Query( array(
'post_type' => 'post',
'post_status' => 'publish',
'name' => $wp->request,
'posts_per_page' => 1,
'nopaging' => true,
'no_found_rows' => true,
) );
if ( $query->found_posts ) {
$redirect_url = add_query_arg( $wp->query_string, '', get_the_permalink( $query->post ) );
wp_safe_redirect( $redirect_url, 301 );
}
}
} );
That is a smart solution.
I have been in same situation and ended up creating redirects.
Cool approach.
MICAH
Thanks for the code.
I’m a writer with a few blogs and most of the code-related things that happen in the bowels of WordPress might as well be magic to me.
So, why would I want to switch my blog post URLs from being at the root-level to using a base path?
NEAL
This is a really good idea, and I bet I’ll end up using it some time. I think what would make this *really* great is if you were to write an .htaccess redirect (or at least log it for later use) on each successful hit. That way, each 404ed post would need to be queried once and then would run a much faster redirect every time thereafter. Great idea, though. Thanks!