WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Following this answer, I recently changed the permalink structure of a custom post type called 'Literature' to include the taxonomy term:

Old structure: mysite.com/literature/books/post_name

New structure: mysite.com/literature/fiction/post_name

However, when visiting the original permalink, Wordpress doesn't automatically redirect it and both pages are appearing as separate entries in Google search.

Should I redirect the old literature permalinks? If so, what's the best way to do this?


Thanks Brian, I've amended your code as below and this is working as desired:

add_action('parse_request', 'redirect_books_to_fiction', 0);
function  redirect_books_to_fiction(){
    global $wp;
    if(preg_match('/literature\/books/', $wp->request)){
        $redirect = get_bloginfo('siteurl').'/'.str_replace('books', get_the_term_list( $ID, 'literature_category', '', ' / ', '' ), $wp->request);
        wp_redirect($redirect, 301);

However, how can I redirect everything and not just 'books'?

On my literature permalinks I can type any word into the trail and it doesn't redirect.

e.g. mysite.com/literature/any_random_word/post_name

Just stays as that permalink.

Whereas, if I visit other pages on my site and change any of the trail leading up to a post, it automatically redirects to the correct permalink.

e.g. If I change: mysite.com/food/recipes/post_name to: mysite.com/a_random_word/another_random_word/post_name

It redirects to the correct permalink.

I assume this is because of the custom permalink structure I used in this answer

Here is the site.

share|improve this question

I concur that you need to add a redirect. You can do this easily with the following function. I'm sure you will have to tweak it, but it's a good proof-of-concept.

add_action('parse_request', 'redirect_books_to_fiction', 0);
function  redirect_books_to_fiction(){
    global $wp;
    if(preg_match_all('~literature\/(.+)/(.+)?~', $wp->request, $matches)){
        $redirect = get_bloginfo('siteurl').'/'.str_replace('books', 'fiction', $wp->request);
        wp_redirect($redirect, 301);

To further answer you question regarding matching segments:

add_action('parse_request', 'redirect_cpts', 0);
function  redirect_cpts(){
    $one_to_one = array(
        'literature' => 'books',
        'food' => 'foo',
        'bar' => 'food'
    $request = $_SERVER['REQUEST_URI'];

    //We limit the scope of the regex to our specified CPTs so we don't hammer every request
    if(preg_match_all('~(literature|food|bar)/(.+)/(.+)?~', $request, $matches)){

        $post_type = $one_to_one[$matches[1][0]]; //Do proper escaping
        $post_name = $matches[3][0]; //Do proper escaping

        if($post_name && $post_type){
            global $wpdb;
            $post = $wpdb->get_row("SELECT * ID FROM $wpdb->posts WHERE post_type = '$post_type' AND post_name = '$post_name'");
            $redirect = get_permalink($post);
                wp_redirect($redirect, 301);
share|improve this answer
Thanks very much Brian. Almost there. I've updated my answer if you could please take a quick look. – fxfuture Feb 4 '12 at 7:00

I would also recommend looking at the plugin Redirection as a good way to manage your changed urls / permalinks

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.