0

So i use CPT with Permalink Manager to change the uri from %postname% to %post_id%. Now that i need to revert the process i'm looking for a function that would redirect all posts from from:

http://domain.com/cpt1/%post_id%

to

http://domain.com/cpt1/%postname%/

Any help appreciated.

1 Answer 1

0

If I understood you correctly, you will first need to redirect your user to http://domain.com/cpt1/%postname%/ and afterward, you'll need to rewrite the URL in order to get the correct post and avoid 404 errors.

So here you go:


add_action( 'template_redirect', 'redirect_postid_to_postname' );

function redirect_postid_to_postname() {

    $uri = $_SERVER['REQUEST_URI'];

    // Checks if the URI matches what we want. This means the URL should be sth like http://example.com/cpt1/POST_ID
    if ( !preg_match( "/^\/cpt1\/(\d+)/", $uri, $matches ) ) {
        return;
    }

    $post_id = $matches[1];

    // Checks if $post_id is actually an existent post ID.
    $post_obj = get_post( $post_id );

    // Checks if a post object was retrieved for the given post ID.
    if ( !$post_obj ) {
        return;
    }

    $post_name = $post_obj->post_name; // Keeps post slug.
    $site_url = get_site_url(); // Keeps site URL (it's supposed to be retrieved without trailing slash).
    $location = $site_url . "/cpt1/$post_name"; // Builds the new URL to redirect the user to.

    // Redirects!
    wp_redirect( $location, 302 );

    exit;

}

add_action( 'init', 'rewrite_custom_postname', 100 );

function rewrite_custom_postname() {

    $uri = $_SERVER['REQUEST_URI'];

    // Checks if the URI matches what we want. This means the URL should be sth like http://example.com/cpt1/POST_NAME
    if ( !preg_match( "/^\/cpt1\/(.+)/", $uri, $matches ) ) {
        return;
    }

    $post_name = $matches[1];

    $query_args = array(
        'name'        => $post_name,
        'post_type'   => 'cpt1',
        'post_status' => 'publish',
        'numberposts' => 1
    );

    $post_obj = get_posts( $query_args );

    // Checks if a post object was retrieved for the given query arguments.
    if ( !$post_obj ) {
        return;
    }

    $post_id = $post_obj[0]->ID;

    $regex = "^cpt1/{$matches[1]}";
    $query = "index.php?p=$post_id";
    $after = "top";

    add_rewrite_rule( $regex, $query, $after );

}

IMPORTANT!
If you are still making use of Permalink Manager and you're also changing the uri from %postname% to %post_id% you might CREATE an infinite loop of redirections, so be careful.
2
  • Uninstalling the plugin will revert all urls at default as far as i know. It's only the redirection part that's needed i think, i'll try this and let you know. Thanks for the effort!! Commented Jun 7, 2017 at 6:29
  • Tried this code, no redirect happens the post just 404 the plugin is disabled. Commented Jun 15, 2017 at 17:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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