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.
Place this plugin in the /wp-content/mu-plugins/redirector.php.
// 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!
});
I'd rather go for a .htaccess redirect anytime but it depends. If you really messed up your blog by changing permalink structure LIVE (which should never be done when some traffic/rankings are achieved), this is a safer method as it only acts when an is_404() occurs. Fine tune it if you have issues with categories, etc.
Warning: PHP 5.3+ Closure used. Consider reverting to PHP 5.2 syntax and compatibility... an assignment :)
posturl
toposturl.html
in the first place? – Scott Jul 14 '11 at 15:04