Redirect all posts urls from without .html to .html


There's a risk with the .htaccess approach. He has to write specific rules to target only posts. Not all URLs on the server.

This is another approach. Works within WordPress, is 'kind-of' safer but a bit performance taxing as it needs to load the plugins before it kicks in. Theory is simple. Redirect any URL not containing . in the last segment like /uri or /uri/ to /uri.html ... ONLY IF WordPress signals a is_404() error.

// Only here we have a valid is_404() to check if occurs.
add_action('wp', function(){
    if(!is_404()) return; // Bail if not a 404 (WordPress has got your back)
    // Extract the URI and the Query-String (which is used later again)
    list($uri, $qs) = explode('?', $_SERVER['REQUEST_URI']);
    // Bail if current URL contains a . in the last segment of the URI
    if(!preg_match('~/[^/\.]+/?$~', $uri)) return;
    // Right-trim the last ./ and append the .html to it
    $uri = rtrim($uri, '/.').".html".(!empty($qs) ? "?{$qs}" : null);
    // Redirect to the new URL (with a 301 to keep link juice flowing) and hope it works :)
    wp_redirect($uri, 301); die; // Over and out!
});

source