Search code examples
wordpress.htaccesshttp-redirectpermalinks

Redirection 301 from /%postname%.html to /%year%/%monthnum%/%postname%.html


I want to change the permalinks from /%postname%.html to /%year%/%monthnum%/%postname%.html.

I know how to do that from Worpdress Admin panel. But I got more than 20000 post, so I want to know please if is any chance to make a redirection from .htacess for old my posts with /%postname%.html redirect to /%year%/%monthnum%/%postname%.html


Solution

  • You should do this in WordPress itself (in contradiction to .htaccess) as you must fetch the real permalink based on the postname.

    Please try updating your permalinks to the new structure and adding the following code to your functions.php file.

    <?php
    function redirect_postname_to_date_structure($wp) {
        $pattern = '#^([^/]+)\.html$#';
        $matches = array();
    
        if ( preg_match( $pattern, $wp->request, $matches ) ) {
            $slug = $matches[1];
    
            $args = array(
                'name' => $slug,
                'post_type' => 'post',
                'post_status' => 'publish',
                'posts_per_page' => 1
            );
    
            // Try to retrieve post based on slug
            $posts = get_posts( $args );
    
            if ( $posts ) {
                $permalink = get_permalink( $posts[0]->ID );
    
                wp_redirect( $permalink, 301 );
                exit;
            }
        }
    }
    add_action( 'parse_request', 'redirect_postname_to_date_structure' );
    ?>
    

    PS: I recommend that you test using the 302 status code (in wp_redirect()) at first. You can switch to 301 when you're confident it works.