I’m afraid Mr. Stern is a bit off from his normally excellent advice. The WP search query string is not a factor for .htaccess rules applied before the WP rule set. If you can rewrite the request before WP “sees” it, it will no longer be a search request.
Part of the problem is query strings are usually stripped before applying any regexp comparisons, so we need to explicitly check against the query string only. The match here can be back referenced in the rewrite rule with %1
. For some reason, rewriting to a permalink doesn’t work, but creating a WP compatible query string is OK.
Also, checking the host name shouldn’t be necessary unless the site uses several aliases and you only want a redirect for one of them. If you do do such a request, you need to account for a possible www by dropping the ^
or adding (www)?\.
after it. Anyway, we end up with this:
RewriteCond %{QUERY_STRING} s=(.*) [NC]
RewriteRule . /index.php/?name=%1? [QSD,R=301]
The final ?
in the rewritten request is supposed to drop the query string – the one place a query string is used but where we don’t want it! For Apache 2.4+ the QSD flag should do the same thing. The problem is, this does not work! It should, but it doesn’t.
The proper syntax for adding a query string is actually example.com/post.php/?s=post-slug (a slash before the ?
) Everyone ignores this, and it normally is not an issue, except for this rule set. If you used the proper syntax, this rule set would work fine. Since everyone neglects that slash, we need to add it with the following first:
RewriteCond %{REQUEST_URI} /post.php$ [NC]
RewriteRule . /post.php/
The initially suggested rule set would actually interfere with a normal WP search query, but since we need to add this other rule, it has the nice side effect of not influencing the WP search query.
The complete rule set, added to .htaccess before the WP rule set:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} /post.php$ [NC]
RewriteRule . /post.php/
RewriteCond %{QUERY_STRING} s=(.*) [NC]
RewriteRule . /index.php/?name=%1? [QSD,R=301]
</IfModule>
Despite all this, at least on my server, a request without that terminal slash with this rule set still fails to strip the original query string. Arrrgh! Fortunately, WP correctly rewrites the name parameter as a permalink. As long as the permalink resolves to an actual post, the errant query string, despite being a valid search query, is ignored. If the original request did happen to have the terminal slash, everything works perfectly.
I haven’t throughly tested this, there may still be particular requests that don’t work right.